清除堆的时间复杂度是多少?
What is the time complexity of clearing a heap?
我搜索了很多网站,他们都说 "the time complexity of clearing a heap is O(n log n)." 原因是:
- 将尾部节点交换到根的成本为 O(1)。
- 将 "the new root" 交换到合适的位置花费 O(level) = O(log n)。
- 所以删除一个节点(根)的成本为 O(log n)。
- 因此删除所有 n 个节点的成本为 O(n log n)。
我认为答案正确但不正确 "tight" 因为:
- 堆(或其级别)在删除过程中变小。
- 因此,"swapping the new root to suitable place"的成本变小了。
- 上述"O(n log n)"的原因不包含这种变化。
创建堆的时间复杂度证明为O(n)在here.
我倾向于认为清除堆的时间复杂度也是 O(n) 因为创建和清除非常相似——都包含 "swapping node to suitable position" 和"change of heap size".
但是,考虑到清理堆的O(n)时间,这里有一个矛盾:
- 通过创建和清除堆,可以在 O(n) 时间内对数组进行排序。
- 排序的时间复杂度下限为O(n log n)。
这个问题我想了一天还是一头雾水
清理堆的成本到底是多少?为什么?
如您正确观察到的那样,所用时间为 O((log n) + (log n-1) + ... + (log 2) + (log 1))。那和O(log(n!))是一样的,跟O(n log n)是一样的(证明在很多地方,但是举个例子:What is O(log(n!)) and O(n!) and Stirling Approximation).
所以你是对的,关于删除堆中每个元素的时间复杂度为 O(nlog n) 的参数是错误的,但结果仍然是正确的。
创建堆和 "clearing" 堆之间的等价性是错误的。当您创建堆时,会有很多松弛,因为堆不变量允许在每个级别进行多种选择,这恰好意味着可以在 O(n) 时间内找到元素的有效排序。当 "clearing" 堆时,就没有这样的松弛(关于比较排序至少需要 n log n 时间的标准证明证明这是不可能的)。
我搜索了很多网站,他们都说 "the time complexity of clearing a heap is O(n log n)." 原因是:
- 将尾部节点交换到根的成本为 O(1)。
- 将 "the new root" 交换到合适的位置花费 O(level) = O(log n)。
- 所以删除一个节点(根)的成本为 O(log n)。
- 因此删除所有 n 个节点的成本为 O(n log n)。
我认为答案正确但不正确 "tight" 因为:
- 堆(或其级别)在删除过程中变小。
- 因此,"swapping the new root to suitable place"的成本变小了。
- 上述"O(n log n)"的原因不包含这种变化。
创建堆的时间复杂度证明为O(n)在here.
我倾向于认为清除堆的时间复杂度也是 O(n) 因为创建和清除非常相似——都包含 "swapping node to suitable position" 和"change of heap size".
但是,考虑到清理堆的O(n)时间,这里有一个矛盾:
- 通过创建和清除堆,可以在 O(n) 时间内对数组进行排序。
- 排序的时间复杂度下限为O(n log n)。
这个问题我想了一天还是一头雾水
清理堆的成本到底是多少?为什么?
如您正确观察到的那样,所用时间为 O((log n) + (log n-1) + ... + (log 2) + (log 1))。那和O(log(n!))是一样的,跟O(n log n)是一样的(证明在很多地方,但是举个例子:What is O(log(n!)) and O(n!) and Stirling Approximation).
所以你是对的,关于删除堆中每个元素的时间复杂度为 O(nlog n) 的参数是错误的,但结果仍然是正确的。
创建堆和 "clearing" 堆之间的等价性是错误的。当您创建堆时,会有很多松弛,因为堆不变量允许在每个级别进行多种选择,这恰好意味着可以在 O(n) 时间内找到元素的有效排序。当 "clearing" 堆时,就没有这样的松弛(关于比较排序至少需要 n log n 时间的标准证明证明这是不可能的)。