Algorithm 左堆队列上heapify的复杂性

Algorithm 左堆队列上heapify的复杂性,algorithm,heap,complexity-theory,leftist-tree,Algorithm,Heap,Complexity Theory,Leftist Tree,Tarjan的“数据结构和网络算法”将heapify功能表述如下: heap function heapify (list q); do |q| ≥ 2 → := q[3..] & meld (q(1), q(2)) od; return if q = [ ] → null | q != [ ] → q(1) fi end heapify; q是我们要一起堆的堆队列meld(h1,h2)是一个用于合并两个堆并恢复堆属性的函数meld(h1,h2)的复杂度为O(logn),其中n

Tarjan的“数据结构和网络算法”将heapify功能表述如下:

heap function heapify (list q);
  do |q| ≥ 2 → := q[3..] & meld (q(1), q(2)) od;
  return if q = [ ] → null | q != [ ] → q(1) fi
end heapify;
q
是我们要一起堆的堆队列
meld(h1,h2)
是一个用于合并两个堆并恢复堆属性的函数
meld(h1,h2)
的复杂度为O(logn),其中n是两个堆中的节点总数。这使得一次通过队列的复杂性如下所示:

heap function heapify (list q);
  do |q| ≥ 2 → := q[3..] & meld (q(1), q(2)) od;
  return if q = [ ] → null | q != [ ] → q(1) fi
end heapify;
(等式1)

这是有道理的。我没有得到的是整个heapify的时间:

(等式2)

k
这是原始堆的数量和它们包含的项目总数。前面还提到了两个约束条件:

(等式3)


有人能帮我理解方程式2是如何推导出来的吗?(如何解释等式2中等式的左边表达式)

我找到了解决方案,结果非常明显:


在每次迭代中,队列元素的数量减半。这使得每次迭代都是k/2。查看所有迭代,该数字以指数形式缩小到2为底,即对于i=0,我们有k;i=1k/2;i=2k/4;i=3 k/8和s.o.这就是为什么总和增加到lg k,堆的数量减少k/(2^i)。等式3中的总和告诉我们,所有元素都分布在当前运行的堆之间。正如我们刚刚计算出的,每次迭代的堆数是k/(2^i)。这就是为什么每个队列运行的meld的最大值是n_i=n/(k/(2_i))=n*(2_i)/k。所有这些共同解释了方程式2,去掉常数后,我们得到了右边的方程式。

我找到了解决方案,结果非常明显:


在每次迭代中,队列元素的数量减半。这使得每次迭代都是k/2。查看所有迭代,该数字以指数形式缩小到2为底,即对于i=0,我们有k;i=1k/2;i=2k/4;i=3 k/8和s.o.这就是为什么总和增加到lg k,堆的数量减少k/(2^i)。等式3中的总和告诉我们,所有元素都分布在当前运行的堆之间。正如我们刚刚计算出的,每次迭代的堆数是k/(2^i)。这就是为什么每个队列运行的meld的最大值是n_i=n/(k/(2_i))=n*(2_i)/k。所有这些共同解释了等式2,去掉常数后,我们得到了右侧的等式。

通过推导,你的意思是为什么等式(2)中的等式成立?不,实际上你是如何得出等式(2)左侧的表达式的。(剩下的只是去掉常数因子,我假设)通过推导,你的意思是为什么等式(2)中的等式成立?不,实际上你是如何得出等式(2)左侧的表达式的。(剩下的只是我假设的常数因子)