您的位置:首页 > 其它

CLRS 堆排序实现和分析

2012-12-12 10:08 218 查看
堆排序是利用堆来进行排序,主要的操作就是建立一个最大堆,最大堆的调整和堆排序。

创建最大堆:从最底层开始进行最大堆调整操作

最大堆调整:找到节点i的最大的儿子,进行交换,递归下去。

堆排序:将堆中的第一个元素与堆尾元素互换,从堆中“去掉”节点n,将堆前1到n-1的元素做最大堆调整,形成新的最大堆。不断将新形成的堆中第一个元素与堆尾的元素互换,调整
堆,最后得到的排好序的结果。

归并排序伪代码如下:

View Code

int parent(int i) {return i>>1;}
int left(int i){return i<<1;}
int right(int i){return i<<1|1;}

void swap(int &a,int &b)
{
int tmp = a;
a = b;
b = tmp;
return;
}

void heapify(int *a, int i, int heapsize)
{
int l, r, max = i;
l = left(i);
r = right(i);

if (l <= heapsize && a[l] > a[i]) max = l;
if (r <= heapsize && a[r] > a[max]) max = r;

if(a[max] > a[i])
{
swap(a[max],a[i]);
heapify(a, max, heapsize);
}
return;
}

void build_max_heap(int *a, int heapsize)
{
for(int i = heapsize/2; i >= 1; i--)
{
heapify(a, i, heapsize);
}
return;
}

void heapsort(int *a, int heapsize)
{
int len = heapsize;
build_max_heap(a,heapsize);
for(int i = heapsize; i >= 1; i--)
{
swap(a[1],a[i]);
len--;
heapify(a, 1, len);
}
return;


对于堆排序的效率,我这里做了实验层面上的分析,400组长度n不同的数组,对于每一个n随机生成100组数据求平均的开销。

下面是实验结果,横坐标是待排序数组的大小,纵坐标是一个count计数:在堆排序中,堆调整时节点与其子节点交换的次数的统计。



最后的结果显示复杂度是O(nlgn)的(可以拟合出曲线对应的函数)。

堆排序是一种比较排序的算法,任何一种基于比较排序的算法在最坏情况下所需要做的比较的次数至少是nlog2n-(n-1)log2e,所以堆排序的的效率已经很高,不可能在数量级上在进行优化了。并且堆排序在平均情况下和最坏情况下,复杂度相差很小,都是O( n*logn)的,这是因为最好和最坏情况的输入只会造成建堆时的运行时间不同,而建堆时复杂度是O(n)的,而堆排序的复杂度主要是堆调整造成的,复杂度是O(nlogn)的。所以,待排序数组的情况对于堆排序的效率影响很小,堆排序的复杂度是很稳定的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐