make_heap 算法 (将一段数据转换为maxheap)

算法描述:

功能:将一段数据转换为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

实例详细分析:

IMG_20130105_174735

原文地址:https://www.cnblogs.com/helloweworld/p/2846408.html