堆的操作的复杂度

堆的两种操作所花的时间都和树的深度成正比.因此,如果一共有n个元素,那么每个操作可以在O(logn)时间内完成.

堆的实现

1.左儿子的编号是自己的编号*2+1

2.右儿子的编号是自己的编号*2+1

push和pop的实现:

 1 int heap[MAX],sz=0;
 2 
 3 void push(int x)
 4 {
 5     //自己节点的编号
 6     int i=sz++;
 7 
 8     while(i>0){
 9         //父亲节点的编号
10         int p=(i-1)/2;
11 
12         //如果已经没有大小颠倒则退出
13         if(heap[p]<=x) break;
14 
15         //把父亲节点的数值放下来,而把自己提上去
16         heap[i]=heap[p];
17         i=p;    
18     }
19 }
20 
21 int pop()
22 {
23     //最小值
24     int ret=heap[0];
25 
26     //要提到根的数值
27     int x=heap[--sz];
28 
29     //从根开始向下交换
30     int i=0;
31     while(i*2+1<sz){
32         //比较儿子的值
33         int a=i*2+1,n=i*2+2;
34         if(b<sz && heap[b]<heap[a])  a=b;
35 
36         //如果已经没有大小颠倒则退出
37         if(heap[a]>=x)
38             break;
39 
40         //把儿子的数组提上来
41         heap[i]=heap[a];
42         i=a;
43     }
44     heap[i]=x;
45     return ret;
46 }

编程语言的标准库:

实际上,大部分情况并不需要自己实现堆.在许多编程语言的标准中,都包含了优先队列的高效实现.例如在c++中,STL里的priority_queue就是其中之一.不过需要注意的是,priority_queue与上面讲的优先队列有所不同,取出数值得到的是最大值.

 1 #include <queue>
 2 #include <cstdio>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     //声明
 8     priority_queue<int> p;
 9 
10     //插入元素
11     p.push(3);
12     p.push(5);
13     p.push(1);
14 
15     //不断循环直到空为止
16     while(!p.empty()){
17         //获取并删除最大值
18         printf("%d
",p.top());
19         p.pop();
20     }
21     return 0;
22 }
原文地址:https://www.cnblogs.com/wangmengmeng/p/5244460.html