【发布时间】:2011-06-30 18:19:34
【问题描述】:
我想知道 C++ 中 make_heap 的算法是什么,使得复杂度为 3*N?我能想到的通过插入元素来创建堆的唯一方法具有 O(N Log N) 的复杂性。非常感谢!
【问题讨论】:
-
@UncleBens那个链接其实显示cost是2n,那
std::make_heap()为什么要取3n呢?
我想知道 C++ 中 make_heap 的算法是什么,使得复杂度为 3*N?我能想到的通过插入元素来创建堆的唯一方法具有 O(N Log N) 的复杂性。非常感谢!
【问题讨论】:
std::make_heap()为什么要取3n呢?
您将堆表示为一个数组。 i'th 元素下方的两个元素位于 2*i+1 和 2*i+2 位置。如果数组有n 元素,那么从末尾开始,取出每个元素,让它“落”到堆中的正确位置。这是O(n) 运行。
为什么? n/2 的元素没有子元素。对于n/4,有一个高度为 1 的子树。对于 n/8,有一个高度为 2 的子树。对于 n/16,有一个高度为 3 的子树。依此类推。所以我们得到了系列n/2<sup>2</sup> + 2*n/2<sup>3</sup> + 3*n/2<sup>4</sup> + ... = (n/2)(1 * (1/2 + 1/4 + 1/8 + . ...) + (1/2) * (1/2 + 1/4 + 1/8 + . ...) + (1/4) * (1/2 + 1/4 + 1/8 + . ...) + ...) = (n/2) * (1 * 1 + (1/2) * 1 + (1/4) * 1 + ...) = (n/2) * 2 = n。所以“看看我是否需要再跌一次,如果需要,我会跌到哪条路?比较的总数是n。但是你从离散化中得到四舍五入,所以你总是小于@987654332 @sets swaps 找出来。每一个最多需要3次比较。(比较root到每个孩子看它是否需要下降,如果root比两个孩子都大,那么孩子相互比较。)
【讨论】: