堆是什么?是一种特殊的完全二叉树

堆:

堆是为了实现排序而设计的一种数据结构,它不是面向查找操作的

堆是什么?是一种特殊的完全二叉树
这棵二叉树有一个特点,就是所有父结点都比子结点要小
符合这样特点的完全二叉树我们称为最小堆。
反之,如果所有父结点都比子结点要大,这样的完全二叉树称为最大堆

假如有14个数分别是99、5、36、7、22、17、46、12、2、19、25、28、1和92。
请找出这14个数中最小的数,请问怎么办呢?最简单的方法就是将这14个数从头到尾依次扫一遍,
用一个循环就可以解决。这种方法的时间复杂度是O(14)也就是O(N)。
for(i=1;i<=14;i++){    
if(a[ i]<min)    
min=a[ i];
}

当新增加一个数被放置到堆顶时,如果此时不符合最小堆的特性,则将需要将这个数向下调整,
直到找到合适的位置为止,使其重新符合最小堆的特性。 
int n =14; 
int a[] = {1,2,5,12,7,17,25,19,36,99,22,28,46,92};   
intp = a;   p[0] =23;  siftdown(0, n, a); //从编号为0开始向下调整;由于数组从0开始,所以我们编号也从0开始   
for(int i =0; i<14; i++) {       
cout<<a[i]<<"\n"; 输出2–7--5–12–22–17–25–19–36–99–23–28–46–92    }
我们刚才在对23进行调整的时候,竟然只进行了3次比较,就重新恢复了最小堆的特性。
现在最小的数依然在堆顶为2。之前那种从头到尾扫描的方法需要14次比较,现在只需要3次就够了。
现在每次删除最小的数并新增一个数,并求当前最小数的时间复杂度是O(3),
这恰好是O(log214)即O(log2N)简写为O(logN)(每次比较完数据剩下一半,比较次数为c,
c个2相乘等于N)。假如现在有1亿个数(即N=1亿),
进行1亿次删除最小数并新增一个数的操作,使用原来扫描的方法计算机需要运行大约1亿的平方次,
而现在只需要1亿
log1亿次,即27亿次。假设计算机每秒钟可以运行10亿次,
那原来则需要一千万秒大约115天!而现在只要2.7秒。

如果只是想新增一个值,而不是删除最小值又该如何操作
先将3与它的父结点25比较,发现比父结点小,为了维护最小堆的特性,需要与父结点的值进行交换。交换之后发现还是要比它此时的父结点5小,
因此需要再次与父结点交换。至此又重新满足了最小堆的特性。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值