Welcom to RO_wsy's blog

堆排序

堆排序是一种高效的比较排序算法,运行时间为O(nlgn)。

这种排序需要用到一种叫做(二叉)堆的数据结构,堆是一种数组对象,也可以看做一颗完全二叉树,对于任一节点,左右子节点和父节点分别可如下简单算出

    PARENT(i) ((i - 1) / 2)
    LEFT(i) (2 * i + 1)
    RIGHT(i) (2 * i + 2)

堆分为大根堆和小根堆,分别具有如下性质:

    a[PARENT(i)] >= a[i]
    a[PARENT(i)] <= a[i]

本文采用大根堆说明堆排序算法的实现。

c++实现源代码如下:

#include <iostream>
using namespace std;
#include <algorithm>

#define LEFT(i) (2 * i + 1)
#define RIGHT(i) (2 * i + 2)

void _max_heapify(int *a, int i, int length)
{
	int l = LEFT(i);
	int r = RIGHT(i);
	int largest = 0;

	if (l < length && a[l] > a[i]) {
		largest = l;
	} else {
		largest = i;
	} 

	if (r < length && a[r] > a[largest]) {
		largest = r;
	}

	if (largest != i) {
		swap(a[largest], a[i]);
		_max_heapify(a, largest, length);
	}
}

void _built_heap(int *a, int length)
{
	for (int i = length / 2; i >= 0; --i) {
		_max_heapify(a, i, length);
	}
}

void heap_sort(int *a, int length)
{
	_built_heap(a, length);

	int i = length - 1;

	while (i >= 1) {
		swap(a[0], a[length - 1]);
		length -= 1;
		_max_heapify(a, 0, length);
		--i;
	}
}

void print(int *a, int length)
{
	for (int i = 0; i < length; ++i) {
		cout << a[i] << endl;
	}
}

int main()
{
	int a[10] = {1, 3, 2, 4, 6, 5, 7, 8, 9, 0};

	heap_sort(a, 10);

	print(a, 10);
}
首先说明_max_heapify函数,这个函数用来保持大根堆的性质,对于给定的以下标为i节点为根的堆是大根堆,如果子节点大于i节点,则两子节点中最大的节点与i节点互换,若两子树依然如此,则递归调用此函数,注意:调用此函数时假设两子树分别为大根堆。

_built_heap函数用来建堆,因为对于length/2以后的元素都是叶子节点,可以看做单节点的大根堆,所以可以对其他节点分别调用_max_heapify函数完成整个堆的建立。为了满足_max_heapify函数的调用规则,应在数组中从后向前遍历。

heap_sort函数用来实现堆排序,因为每次建堆后第一个元素即是数组中的最大元素,所以将它放到最后即可,然后对其余元素继续此过程,直至数组剩余两个元素为止,至此排序完成。

posted @ 2012-10-14 22:33  RO_wsy  阅读(155)  评论(0编辑  收藏  举报