算法描述:
功能:将一段数据转换为max-heap.(父节点不小于子节点的完全二叉树。)
基本步骤:
从某一子树开始进行下溯操作。
开始的子树:Distance parent = (len - 2)/2; 最后的叶节点不必执行下溯。
该子树执行完下溯后parent—;
下溯:将空洞节点(这里是parent,即开始执行下溯的节点)与较大子节点对调,并持续下放,
直到叶节点为止。
SGI STL实现:
// 以下這組 make_heap() 不允許指定「大小比較標準」。 template <class RandomAccessIterator, class T, class Distance> void __make_heap(RandomAccessIterator first, RandomAccessIterator last, T*, Distance*) { if (last - first < 2) return; // 如果長度為 0 或 1,不必重新排列。 Distance len = last - first; // 找出第一個需要重排的子樹頭部,以 parent 標示出。由於任何葉節點都不需執行 // perlocate down,所以有以下計算。parent 命名不佳,名為 holeIndex 更好。 Distance parent = (len - 2)/2; while (true) { // 重排以 parent 為首的子樹。len 是為了讓 __adjust_heap() 判斷操作範圍 __adjust_heap(first, parent, len, T(*(first + parent))); if (parent == 0) return; // 走完根節點,就結束。 parent--; // (即將重排之子樹的)頭部向前一個節點 } }
// 將 [first,last) 排列為一個 heap。 template <class RandomAccessIterator> inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) { __make_heap(first, last, value_type(first), distance_type(first)); }
测试实例:
#include <vector> #include <iostream> #include <algorithm> using namespace std; int main() { int iarray[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,}; vector<int> ivec(iarray, iarray + 11); make_heap(ivec.begin(), ivec.end()); for (int i = 0; i < ivec.size(); ++i) { cout << ivec[i] << ' '; } return 0; }
输出:
10 9 6 8 4 5 2 7 3 1 0