二叉堆
2016-05-20 15:55
239 查看
二叉堆是一种高级的数据结构,用来动态维护一个序列中的最值和对某一个数的删除或插入。堆满足下列性质:
【删除】 假如我们要删除数组中第一个数,只要把第一个数和最后一个数进行交换就行了。这时,又会出现一些不符合堆的性质的情况出现:如H[p]<H[ left(p) ]或H[p]<H[ right(p) ]的情况出现。那么,我们把它们交换不就可以了!但是,我们还有一个问题,假如H[p]<H[ left(p) ]和H[p]<H[ right(p) ]的情况都出现,那么应该交换那个呢?应该是较大的那一个。为什么呢?
我们都知道,一个节点p的左孩子是p*2,右孩子是p*2+1,所以,我们可以从上往下进行比较并交换。
以上就是一些关于堆的相关操作,时间效率都是O(logn)的。因此堆是一种非常有用的数据结构!
1,堆是一棵完全二叉树。(因此可以用数组来表示且不浪费空间) 2,堆的每一个父亲节点的值均≥(大根堆)或≤(小根堆)其左右孩子的值。(下面若没有注明,均讨论大根堆)下面来看一下堆的相关操作:【最值】 最值就不用说了吧,直接输出根节点就行了。因为根节点都大于等于其左右孩子,而它的左右孩子又大于等于其左右孩子……。【插入】 为了方便,插入时一般在数组的尾部,但插入后会出现一些不符合堆的性质的情况:h[ p ]>=h[ father(p) ],这是我们把它们交换,就可以维护性质了。但交换后还是可能出现违背性质的情况,所以,我们要从下往上进行交换。众所周知,father(p)=p/2,因此可以用p/2的步骤找到自己的父亲并进行交换。
void insert(int p) { h[++m]=p; int j=m; while((j>>1)>0 && h[j]>h[j>>1]) { swap(h[j],h[j>>1]); j>>=1;// j=j>>1; 相当于j=j/2; } return; }
【删除】 假如我们要删除数组中第一个数,只要把第一个数和最后一个数进行交换就行了。这时,又会出现一些不符合堆的性质的情况出现:如H[p]<H[ left(p) ]或H[p]<H[ right(p) ]的情况出现。那么,我们把它们交换不就可以了!但是,我们还有一个问题,假如H[p]<H[ left(p) ]和H[p]<H[ right(p) ]的情况都出现,那么应该交换那个呢?应该是较大的那一个。为什么呢?
我们都知道,一个节点p的左孩子是p*2,右孩子是p*2+1,所以,我们可以从上往下进行比较并交换。
int Delete()//删除并输出最大值 { int ans=h[1]; h[1]=h[m--]; int j=1,k; while( j<<1<=m ) { k=j<<1; if(k<m && h[k]<h[k+1]) k++;//比较左孩子和右孩子的大小 if(h[k]<=h[j]) break; swap(h[j],h[k]);//交换 j=k; } return ans;//最大值 }
以上就是一些关于堆的相关操作,时间效率都是O(logn)的。因此堆是一种非常有用的数据结构!
相关文章推荐
- USACO 2016 JAN——Angry Cows套题的解题报告
- 2009南海区集训队初中选拔题1的解题报告
- 2016.3.13的解题报告
- 全排列
- 2016.3.20的解题报告
- 【编程技巧】——加快cin的输入速度
- 【编程技巧】——对拍
- RMQ
- 【编程技巧】——计算时间
- 2016GDOI市选拔赛解题报告
- 【转载】胜者树
- 【转载】计算几何中的精度问题(转)
- USACO 2016 open Bronze 解题报告
- SPFA
- USACO 2016 open Silver 解题报告
- 2016GDOI的总结
- 六十一 Web开发 使用Web框架
- js判断 微信浏览器 或者 QQ内置浏览器
- redis
- jquery.nicescroll.js可全屏可改滚动条颜色的滚动条插件-推荐