【发布时间】:2011-09-12 02:14:49
【问题描述】:
我查看了 C++0x 标准,发现 make_heap 的比较不能超过 3*N 的要求。
即heapify 一个无序的集合可以在 O(N) 中完成
/* @brief Construct a heap over a range using comparison functor.
这是为什么?
来源没有给我任何线索(g++ 4.4.3)
while (true) + __parent == 0 不是线索,而是对 O(N) 行为的猜测
template<typename _RandomAccessIterator, typename _Compare>
void
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
const _DistanceType __len = __last - __first;
_DistanceType __parent = (__len - 2) / 2;
while (true)
{
_ValueType __value = _GLIBCXX_MOVE(*(__first + __parent));
std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value),
__comp);
if (__parent == 0)
return;
__parent--;
}
}
__adjust_heap 看起来像 log N 方法:
while ( __secondChild < (__len - 1) / 2)
{
__secondChild = 2 * (__secondChild + 1);
对我来说是一个沼泽标准日志 N。
template<typename _RandomAccessIterator, typename _Distance,
typename _Tp, typename _Compare>
void
__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
_Distance __len, _Tp __value, _Compare __comp)
{
const _Distance __topIndex = __holeIndex;
_Distance __secondChild = __holeIndex;
while (__secondChild < (__len - 1) / 2)
{
__secondChild = 2 * (__secondChild + 1);
if (__comp(*(__first + __secondChild),
*(__first + (__secondChild - 1))))
__secondChild--;
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild));
__holeIndex = __secondChild;
}
if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2)
{
__secondChild = 2 * (__secondChild + 1);
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first
+ (__secondChild - 1)));
__holeIndex = __secondChild - 1;
}
std::__push_heap(__first, __holeIndex, __topIndex,
_GLIBCXX_MOVE(__value), __comp);
}
任何关于为什么这是 O 编辑:
实验结果:
这个实际实现使用
【问题讨论】:
-
指出并解释为什么您发布的来源支持您的猜想。我并不是说它没有,只是我懒得去趟过它。
-
您可能想在Wikipedia 上查看为什么 heapify 是 O(n) 的解释。
-
@trutheality O(n) 在那篇文章中没有提到,我错过了什么。
-
@truth 因子 3 从何而来?
-
@Mike:它在“构建堆”部分。
标签: c++ algorithm stl big-o binary-heap