首页 > 代码库 > 数据结构:堆排序

数据结构:堆排序

「仅为草稿,尚未详解」

堆排序(C语言版)

走进堆排序

什么是堆

堆实质就是一颗完全二叉树,其任何一非叶子节点满足下列性质。

技术分享i=1,2,3...n/2

 说明:

  既然是完全二叉树,我们就可以用数组来表示!

 堆根据上面的性质又分为:

技术分享技术分享

  从中不难发现,大顶堆从上往下依次键值减小小顶堆从上向下键值增大

什么是堆排序

? 对一组待排序记录的关键字,首先把它们按堆的定义建成小(大)顶堆
? 然后输出堆顶的最小(大)关键字所代表的记录再对剩余的关键字建堆以便得到次小(大)的关键字
? 如此反复进行直到全部关键字排成有序序列为止。

我们先对排序的过程进行了解(已经建好堆)

我曾在优先队列的博客中介绍过大顶堆的这种构造新堆的方法:由上至下的堆有序化。这里同样类似。

  技术分享

?我们如何将堆有序转换成我们想要的排序结果呢? 

  即,我们想要将这颗完全二叉树变成结果:12 24 30 36 47 53 85 91..
  我们可以不断的执行上诉操作,即不断取出堆顶元素,然后再进行堆有序化,再取出堆顶元素,反复。

 核心算法

void HeapAdjust (SqList &H, int s, int m)
{
    for(int j=2*s;j<=m;j*=2)
    {
        if(j<m&&H.r[j].key>H.r[j+1].key) ++j;
        if(H.r[s].key<H.r[j].key) break;
        int temp = H.r[s].key;
        H.r[s].key=H.r[j].key;
        H.r[j].key=temp;
        s=j;
    }

}
void sortByHeapSort(SqList &L)
{
    for(int i=L.length/2;i>0;i--)
    {
        HeapAdjust(L,i,L.length);
    }
    for (int i = L.length; i > 1; --i)    {
        int temp = L.r[1].key;
        L.r[1].key=L.r[i].key;
        L.r[i].key=temp;
        HeapAdjust (L, 1, i - 1); //将H. r[l .. i - 1] 重新调整为大/小顶堆
    }
}

算法分析

  时间复杂度:O(nlog2n) 空间复杂度:O(1)
  是一种不稳定的排序方法

数据结构:堆排序