的背景
根据维基百科和我发现的其他来源,通过从一个空的二进制堆开始并将n 个元素插入其中来构建一个包含n 个元素的二进制堆是 O( n log n ),因为二进制堆插入是 O(log n )你做了n次。我们称之为插入算法。
它还提供了一种替代方法,您可以在其中下沉/涓涓细流/向下渗透/向下层叠/向下堆积/向下冒泡元素的前半部分/上半部分,从中间元素开始,到第一个元素结束,这是O( n ),一个更好的复杂度。这种复杂性的证明取决于每个元素的接收器复杂性取决于它在二进制堆中的高度:如果它靠近底部,它会很小,可能为零;如果它靠近顶部,它可能很大,可能是 log n。关键是这个过程中下沉的每个元素的复杂度不是log n,所以整体复杂度远小于O( n log n ),实际上是O( n)。我们称其为接收器算法。
问题
为什么插入算法的复杂度与接收器算法的复杂度不同,原因相同?
考虑为插入算法中的前几个元素所做的实际工作。第一次插入的成本不是 log n,它是零,因为二进制堆是空的!第二次插入的成本最坏是一次交换,第四次插入的成本最坏是两次交换,依此类推。插入元素的实际复杂度取决于二叉堆的当前深度,因此大多数插入的复杂度小于 O(log n )。插入成本在技术上甚至不会达到 O(log n ) ,直到插入所有n 个元素 [最后一个元素的 O(log ( n - 1))]!
这些节省听起来就像接收器算法获得的节省,那么为什么两种算法的计算不一样呢?