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; _