为什么pop_heap()函数的实现会调用另一个push_heap()函数?

时间:2013-12-26 07:40:42

标签: c++ stl

template <class RandomAccessIterator, class Distance, class T>
void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
                   Distance len, T value) {
  Distance topIndex = holeIndex;
  Distance secondChild = 2 * holeIndex + 2;
  while (secondChild < len) {
    if (*(first + secondChild) < *(first + (secondChild - 1)))
      secondChild--;
    *(first + holeIndex) = *(first + secondChild);
    holeIndex = secondChild;
    secondChild = 2 * (secondChild + 1);
  }
  if (secondChild == len) {
    *(first + holeIndex) = *(first + (secondChild - 1));
    holeIndex = secondChild - 1;
  }
  __push_heap(first, holeIndex, topIndex, value); **//why?**
}

template <class RandomAccessIterator, class T, class Distance>
inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
                       RandomAccessIterator result, T value, Distance*) {
  *result = *first;
  __adjust_heap(first, Distance(0), Distance(last - first), value);
}

template <class RandomAccessIterator, class T>
inline void __pop_heap_aux(RandomAccessIterator first,
                           RandomAccessIterator last, T*) {
  __pop_heap(first, last - 1, last - 1, T(*(last - 1)), distance_type(first));
}

template <class RandomAccessIterator>
inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) {
  __pop_heap_aux(first, last, value_type(first));
}
从下到上,有四个功能。调整堆的实际操作在__adjust_heap中。

现在我们查看代码。在 while 循环之后,有一个 if 块,它会交换 holeIndex 处的元素和 holeIndex 处的元素的孩子。然后调用__push_heap()。

我认为没有必要调用__push_heap()函数,如果在 if 语句中添加一个额外的判断,就像这样。

  if (secondChild == len && *(first + holeIndex) < *(first + (secondChild - 1))) {
    *(first + holeIndex) = *(first + (secondChild - 1));
    holeIndex = secondChild - 1;
  }

我提出了我的断言背后的推理。

当程序运行到 if 语句时, secondChild 的元素必须大于 len 或等于 len 的。这意味着 secondChild 没有正确的孩子并且可能有一个左子。所以, secondChild 必须是max_heap上的最后一个非叶子节点,并且它的左子节点必须是叶节点(如果存在)。它只需要比较 secondChild 的元素及其左子元素。 Left-child的元素必须小于 secondChild 的父元素,因此,我认为没有必要调用__push_heap()来渗透。

由于我的英语不好,很难正确描述我的想法......&gt; _

0 个答案:

没有答案