建堆
算法:build-max-heap
目标:数组转换最大堆
方法:自底向上
过程:MAX-HEAPIFY
算法描述:
build-max-heap(i){
A.heap-size = A.length
for i = [A.length/2] downto 1
Max-heapify(A,i)
}
算法正确性证明:
建立循环不变量,即在算法第2-3行中每一次for循环的开始,结点i+1,i+2,...,n都是一个最大堆的根结点。
初始化:
在第一次循环迭代之前,i=[n/2],[n/2]+1、[n/2]+2、...,n都是叶结点,因而是平凡最大堆的根结点。
保持:
max-heapify维护了结点i+1,i+2,...,n都是一个最大堆的根结点的性质。在for循环中递减i,为下一次循环重新建立循环不变量。
终止:
i=0,过程终止。每个结点都是一个最大堆的根。
build-max-heap运行时间上界:
简单估计:调用max-heapify时间复杂度是O(lgn),调用build-max-heap时间复杂度在O(n),总时间复杂度大约在O(nlgn)。
渐进紧确:
-
包含n个元素的堆的高度为[lgn]
-
高度为h的堆最多包含[n/2^(k+1)]个结点
在一个高度为h的结点上运行Max-heapify的代价是O(h),所以build-max-heap的总代价表示为:
最后一个累积和的计算用x=1/2代入得到
由此得到build-max-heap时间复杂度(即上上式右边)等于O(n)。实现在线性时间内把一个无序数组构造成一个最大堆。
一个建堆例子: