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

堆:

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

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

假如有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=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< 我们刚才在对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小,
因此需要再次与父结点交换。至此又重新满足了最小堆的特性。

你可能感兴趣的:(堆是什么?是一种特殊的完全二叉树)