参考资料:http://www.7747.net/kf/201104/88993.html 《大话数据结构》第9章 排序 9.7 堆排序
以上页面非常详细以源码+图示的方法讲述了堆排序的全部过程,在此记录,仅为个人学习笔记。
堆排序的基本思想为:将待排序的序列构造成大顶堆(大顶堆:非叶子节点的儿子均小于父亲节点的完全二叉树(完全二叉树,最底一层不必满,不是满二叉树)),该堆的根节点为最大元素,将此元素取出,然后将最后一个元素换至根节点处,再次构造大顶堆,循环至所有元素取出。堆排序的的算法复杂度为O(nlogn)。
堆排序实现过程中的关键有两点:
1、如何将无序序列建立成大顶堆
首先将无序序列按照原先顺序放入完全二叉树中,然后用HeapAdjust()函数对其进行大顶化。
2、当输出堆顶元素后,如何将剩余元素形成新的大顶堆
当最后一个元素移至堆顶后,即可用HeapAdjust()对其大顶化。
代码如下:
//SqList为存储无序序列的队列
void HeapSort(SqList *L)
{
int i;
for(i = L->length/2; i > 0; i--)
{
//L为存储大顶堆的数组,i为起始节点,L->length为最后的节点
HeapAdjust(L, i, L->length);
}
for(i = L->length; i > 1; i--)
{
swap(L, 1, i);
HeapAdjust(L, 1, i - 1);
}
}
void HeapAdjust(SqList *L, int s, int m)
{
int temp, j;
temp = L->r[s];
for(j = 2 * s; j <= m; j *= 2)
{
if(j < m && L->r[j] < L->r[j+1])
++j;
if(temp >= L->r[j])
break;
L->r[s] = L->r[j];
s = j;
}
L->r[s] = temp;
}
void swap(SqList *L, int s, int m)
{
printf("%d/n", L->r[s]);
L->r[s] = L->r[m];
}