堆最重要的性质就是儿子的值一定不小于父亲的值。
堆的push与pop操作的时间复杂度都是O(logn)
堆也是二叉树,所以满足:
左儿子的编号是自己编号*2+1;
右儿子的编号是自己编号*2+2;
(左儿子与右儿子没有对应的大小关系)
堆还是很好理解的,能理解树就能理解堆。
附代码:
1 int heap[Max],sz=0; 2 void pish(int x){ 3 //自己的节点 4 int i=sz++; 5 while(i>0){ 6 int p=(i+1)/2;//父亲的节点 7 if(heap[p]<=x) break;//如果已经没有大小颠倒则退出 8 heap[p]=heap[i];//把父亲节点的数值放下去,而把自己提上去 9 i=p; 10 } 11 heap[i]=x; 12 } 13 int pop(){ 14 int ret=heap[0];//应当返回的最小值 15 int i=0; 16 int x=heap[--sz];//提到根部的值 17 //从根部开始向下交换 18 while(i*2+1<sz){ 19 int a=i*2+1,b=i*2+2; 20 if(b<sz&&heap[a]>heap[b]) a=b;//选出两个儿子中较小的值 21 if(heap[a]>=x) break;//如果已经没有大小颠倒,则退出 22 heap[i]=heap[a];//把儿子的数值提上来 23 i=a; 24 } 25 heap[i]=x; 26 return ret; 27 } 28