1. 程式人生 > >(模板)堆的快速搭建

(模板)堆的快速搭建

堆排序是指使用堆結構對一個序列進行排序的過程,此處討論遞增排序的情況

考慮對一個堆來說,堆頂元素是最大的,因此在建堆完畢後,思路就是取出堆頂元素,然後將堆的最後一個元素替換至堆頂,再進行一次針對堆頂元素的向下調整--如此重複,直到堆中剩下最後一個元素為止

如此重複,直到堆中只剩下最後一個元素為止

我們可以直接用一個數組來表示堆,

const int maxn = 1001;
int heap[maxn], n = 10;   //n表示元素個數

堆的調整函式,其中low是堆頂元素位置

void downAdjust(int low, int high) {   //low表示最低的元素下標,high表示陣列的最後一個元素的下標
	int current = low, lchild = current * 2;   //j表示左孩子
	while (lchild <= high) {       //如果左孩子存在
		//如果右孩子存在,且右孩子的值大於當前結點值
		if (lchild + 1 <= high && heap[lchild] < heap[lchild + 1]) {
			lchild = lchild + 1;   //改成右節點
		}
		if (heap[lchild] > heap[current]) {
			swap(heap[lchild], heap[current]);
			current = lchild;
			lchild = current * 2;
		}
		else {
			break;
		}
	}
}

堆的建立:我們根據數學原理可以知道,完全二叉樹中葉子結點個數=結點個數/2;

所以我們只需從上至下對非葉子結點進行調整就可以了

//堆的建立
void createHeap() {  //建立堆:把堆進行排序
	for (int i = n / 2; i >= 1; i--) {   //
		downAdjust(i, n);
	}
}

插入:新元素先插入底部,然後自下而上與父類進行比較並放置到合適的位置

void insert(int x) {
	heap[++n] = x;
	int current = n;
	int father = n / 2;
	while (father >= 1 && heap[current] > heap[father]) {
		swap(heap[current], heap[father]);
		current = father;
		father = current / 2;
	}
}

遍歷:直接按序輸出陣列,層序遍歷即可

void traverse() {
	for (int i = 1; i <= n; ++i) {
		cout << heap[i] << " ";
	}
	cout << endl;
}

堆排序:(依次將頂部元素與底部元素逐個交換,然後對堆到該底部元素的位置進行調整)

void heapSort() {
	for (int i = n; i > 1; --i) {
		swap(heap[1], heap[i]);
		downAdjust(1, i-1);
		traverse();
	}
}

整體程式碼如下:

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1001;
int heap[maxn], n = 10;   //n表示元素個數

void downAdjust(int low, int high) {   //low表示最低的元素下標,high表示陣列的最後一個元素的下標
	int current = low, lchild = current * 2;   //j表示左孩子
	while (lchild <= high) {       //如果左孩子存在
		//如果右孩子存在,且右孩子的值大於當前結點值
		if (lchild + 1 <= high && heap[lchild] < heap[lchild + 1]) {
			lchild = lchild + 1;   //改成右節點
		}
		if (heap[lchild] > heap[current]) {
			swap(heap[lchild], heap[current]);
			current = lchild;
			lchild = current * 2;
		}
		else {
			break;
		}
	}
}

void createHeap() {  //建立堆:把堆進行排序
	for (int i = n / 2; i >= 1; i--) {   //
		downAdjust(i, n);
	}
}

void insert(int x) {
	heap[++n] = x;
	int current = n;
	int father = n / 2;
	while (father >= 1 && heap[current] > heap[father]) {
		swap(heap[current], heap[father]);
		current = father;
		father = current / 2;
	}
}

void traverse() {
	for (int i = 1; i <= n; ++i) {
		cout << heap[i] << " ";
	}
	cout << endl;
}

void heapSort() {
	for (int i = n; i > 1; --i) {
		swap(heap[1], heap[i]);
		downAdjust(1, i-1);
		traverse();
	}
}

int main() {
	cin >> n;
	for (int i = 1; i <= n; ++i) {
		cin >> heap[i];
	}

	system("PAUSE");
	return 0;
}