考虑以下用于构建输入数组 A 的堆的算法。
BUILD-HEAP(A)
heapsize := size(A);
for i := floor(heapsize/2) downto 1
do HEAPIFY(A, i);
end for
END
快速浏览上述算法表明运行时间是 ,因为每次调用Heapify 都会花费和Build-Heap使得这样的电话。
这个上限虽然正确,但并不是渐近紧的。
我们可以通过观察Heapify的运行时间取决于树 ‘h’ 的高度(等于 lg(n),其中 n 是节点数)和大多数子树的高度来推导出更严格的界限小的。
当我们沿着树向上移动时,高度“h”会增加。 Build-Heap的第 3 行运行一个循环,从最后一个内部节点 (heapsize/2) 的索引(高度 = 1)到 root(1) 的索引(高度 = lg(n))。因此, Heapify为每个节点花费不同的时间,即 .
为了找到构建堆的时间复杂度,我们必须知道高度为 h 的节点数。
为此,我们使用这样一个事实,一个大小为 n 的堆最多有高度为 h 的节点。
现在为了推导出时间复杂度,我们将构建堆的总成本表示为-
(1)
步骤 2 使用 Big-Oh 符号的属性忽略天花板函数和常数 2( )。类似地,在第三步中,由于我们使用的是 Big-Oh 符号,因此总和的上限可以增加到无穷大。
无限 GP (x < 1) 的总和
(2)
两边微分并乘以x,我们得到
(3)
将(3)中得到的结果放回到我们的推导(1)中,我们得到
(4)
因此证明构建二叉堆的时间复杂度为 .
参考 :
http://www.cs.sfu.ca/CourseCentral/307/petra/2009/SLN_2.pdf
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。