二叉堆

        二叉堆是一种高级的数据结构,用来动态 维护一个序列中的最值和对某一个数的删除或插入。堆满足下列性质:
 
   
        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) ]的情况都出现,那么应该交换那个呢?应该是较大的那一个。为什么呢?
二叉堆 - 区庆亮 - oql
 
我们都知道,一个节点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)的。因此堆是一种非常有用的数据结构!

转载于:https://www.cnblogs.com/ouqingliang/p/9245331.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值