c++堆排序实现(heapsort) (算法导论)

利用最大堆实现。

最大堆:最大堆性质是除了根结点意外的所有结点 i 都要满足A[parent[i]] >= A[i]

需要利用到的一个性质:当用数组表示存储n个元素的堆时,叶结点的下标分别是n/2, n/2+1, n/2 + 2, ……,n – 1.  (下标从0开始)

需要用到的函数有:

void max_heapify(int *a, int i)    //通过让a[i]的值在最大堆中“逐级下降”,从而使得以下标i为根结点的字数重新遵循最大堆的性质。O(lgn)

void build_max_heap(int *a)            //对树中非叶结点都调用一次max_heapify(a, i)。  O(n)

void heapsort(int *a, int n)        //对长度为n的数组a调用堆排序。  O(nlgn)

//heapsort.cpp
inline void swap(int &a, int &b) { int t = a; a = b; b = t; }
inline int parent(int i) { return (i-1) >> 1; }         //下标都是从0开始,与算导上不一样
inline int left(int i) { return (i << 1) + 1; }
inline int right(int i) { return (i << 1) + 2; }

int heap_size, heap_length;          //heap_length是数组元素个数,heap_size是有多少个元素存储在数组中。0<=heap_size<=heap_length

void max_heapify(int *a, int i) {             //O(lgn), 维护heap的性质,使得以下标i为根结点的子树重新遵循最大堆的性质
	int l = left(i), r = right(i);
	int largest = 0;
	if (l < heap_size && a[l] > a[i])
		largest = l;
	else
		largest = i;
	if (r < heap_size && a[r] > a[largest])
		largest = r;
	if (largest != i) {
		swap(a[i], a[largest]);
		max_heapify(a, largest);
	}
}

void build_max_heap(int *a) {             //O(n), 对树中非叶结点都调用一次 max_heapify
	heap_size = heap_length;
	for (int i = heap_length/2 - 1; i >= 0; --i)   //可以证明下标为n/2-1到0的结点为非叶结点
		max_heapify(a, i);              //i逆序递减的原因:任何时候对结点i调用max_heapify,该i的两个子树都是最大堆
}

void heapsort(int *a, int n) {           //O(nlgn),调用heapsort(a, n)对数组a排序
	heap_length = n;
	build_max_heap(a);
	for (int i = heap_length - 1; i >= 1; --i) {
		swap(a[0], a[i]);
		--heap_size;
		max_heapify(a, 0);
	}
}

    原文作者:排序算法
    原文地址: https://blog.csdn.net/pegasuswang_/article/details/20702919
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞