「仅为草稿,尚未详解」
堆排序(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)
是一种不稳定的排序方法
时间: 2024-10-10 13:56:27