Изменить: это не спрашивает, как сделать std::make_heap
путь O (n), а не является ли эта конкретная реализация действительно O (n)
Учебный способ построения кучи в O (n) времени состоит в том, чтобы последовательно строить кучу снизу вверх. Но реализация std::make_heap
на моей машине Mac в libС++ - это
template <class _RandomAccessIterator, class _Compare>
inline _LIBCPP_INLINE_VISIBILITY
void
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
{
#ifdef _LIBCPP_DEBUG
typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
__debug_less<_Compare> __c(__comp);
__make_heap<_Comp_ref>(__first, __last, __c);
#else // _LIBCPP_DEBUG
typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
__make_heap<_Comp_ref>(__first, __last, __comp);
#endif // _LIBCPP_DEBUG
}
где __make_heap
определяется как
template <class _Compare, class _RandomAccessIterator>
void
__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
difference_type __n = __last - __first;
if (__n > 1)
{
__last = __first;
++__last;
for (difference_type __i = 1; __i < __n;)
__push_heap_back<_Compare>(__first, ++__last, __comp, ++__i);
}
}
template <class _Compare, class _RandomAccessIterator>
void
__push_heap_back(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len)
{
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
if (__len > 1)
{
__len = (__len - 2) / 2;
_RandomAccessIterator __ptr = __first + __len;
if (__comp(*__ptr, *--__last))
{
value_type __t(_VSTD::move(*__last));
do
{
*__last = _VSTD::move(*__ptr);
__last = __ptr;
if (__len == 0)
break;
__len = (__len - 1) / 2;
__ptr = __first + __len;
} while (__comp(*__ptr, __t));
*__last = _VSTD::move(__t);
}
}
}
Разве это не просто итеративная вставка в кучу, а с временной сложностью O (n log n)? Я прав, что это ошибка?