Как реализовать std :: make_heap при сравнении не более 3N?

Я посмотрел на стандарт C ++ 0x и обнаружил, что make_heap должен выполнять не более 3 * N сравнений.

Т.е. Скопировать неупорядоченный набор можно в 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);      
      }

Будут оценены любые подсказки, почему это & ​​lt; = 3 Н.
РЕДАКТИРОВАТЬ:

Экспериментальные результаты:

Эта фактическая реализация использует сравнения

  • < 2N для куч кучи
  • < 1,5N для куч кучи в обратном порядке.
28
задан templatetypedef 31 January 2012 в 21:55
поделиться