当前位置:   article > 正文

排序算法——优先队列(基于堆得优先队列)_优先队列基于堆

优先队列基于堆

一:数据结构 堆的概念

1.堆

    堆数据结构是一种数组对象,它可以被视为一科完全二叉树结构。它的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆)。它常用于管理算法执行过程中的信息,应用场景包括堆排序优先队列等。


堆有两个很基本的操作:增加、删除。先来说说增加元素,假设有下面这样一个堆:

这时候,有一个元素1要添加进来,这时候应该怎么办呢?第一步,将元素添加到堆的最后一个位置:

第二步,将新加入的元素与其父结点的值进行比较,若新结点的值比其父结点的值要小(就像这个例子一样),那么,交换两个结点的值,重复第二步,直到形成一个小顶堆:

这样,一个新的小顶堆诞生了!

然后就是从堆中删除一个元素了,假设在这个新的小顶堆中,我们打算删除值为1的那个结点:

第一步,将这个1删掉,假设其结点上当前没有值:

第二步,比较该删除结点(当前是最上面的那个)的两个子结点,看谁的值小,交换其中较小值和这个空结点的值(假设是null),然后重复这一步,直到该空值到最小面一行:

第三步,就是将这个空的结点从视线中移除了,这样,删除的过程就告一段落了(好吧,这个堆又回到解放前了)!


优先队列是由一个基于堆的完全二叉树表示,存储于数组pq[1..N]中,pq[0]没有使用。在insert()中,我们将N加一并把新元素添加到数组最后,然后用swim上浮恢复堆得秩序。在DelMax()中,我们从pq[1]中得到需要返回的元素,然后将pq[N]移动到pq[1],将N减一并用sink()恢复堆的秩序。


代码:

  1. package suanfa;
  2. public class MaxPQ {
  3. static int pq[]={0,13,9,8,7,6,5,4,3,2,0};
  4. static int N=pq.length-2;
  5. public static void insert(int m) //插入元素
  6. {
  7. pq[++N]=m; //放在最后
  8. swim(N); //上浮操作
  9. }
  10. private static void swim(int n) {
  11. while(n>1&&less(n/2,n))
  12. {
  13. exch(n/2,n);
  14. n=n/2;
  15. }
  16. }
  17. private static void sink(int n) {
  18. while(2*n<=N) //循环条件1
  19. {
  20. int j=2*n;
  21. if(j<N&&less(j,j+1)) j++; //选择子节点较大的那个
  22. if(less(j,n)) break;//当子节点比父节点小,跳出循环
  23. exch(n,j);//交换父子节点
  24. n=j;
  25. }
  26. }
  27. private static void delMax()
  28. {
  29. int max=pq[1];
  30. exch(1, N--);//交换首尾节点
  31. pq[N+1]=0;
  32. sink(1);//下沉操作
  33. }
  34. static boolean less(int a,int b)
  35. {
  36. return pq[a]<pq[b];
  37. }
  38. static void exch(int i,int j){
  39. int temp=pq[i];
  40. pq[i]=pq[j];
  41. pq[j]=temp;
  42. }
  43. static int max(int i,int j){
  44. if(less(i,j))
  45. return pq[j];
  46. else return pq[i];
  47. }
  48. public static void main(String[] args) {
  49. //MaxPQ.insert(10);
  50. MaxPQ.delMax();
  51. for(int i=1;i<N+1;i++)
  52. {
  53. System.out.print(pq[i]+",");
  54. }
  55. }
  56. }


本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/943742
推荐阅读
相关标签
  

闽ICP备14008679号