HeapSort
1.不稳定排序
2.时间复杂度,最好最坏与平均都为o(nlog2n)
3.空间复杂度,仅使用了数个辅助单元,为o(1)
4.适合关键字较多的情况,利用了顺序存储的随机访问特性
提示:以下是本篇文章正文内容,下面案例可供参考
一、堆排序概述
如上图所示,一组数据可建立一个类似完全二叉树的图形。
而完全二叉树按从上到下,从左到右依次编号1,2,3,4…n。当2i<n时,节点i的左孩子为2i;当2i+1<n时,节点i的右孩子为2i+1。
堆排序利用了大根堆父母节点大于子节点的特性,即L(i)>=L(2i)且L(i)>=L(2i+1),来对数据进行递增排序。
二、代码
1.建立大根堆
代码如下(示例):
void HeapAdjust(int a[], int k, int len) //调整以元素k为根的子树
{
int i;
a[0] = a[k]; //存储根节点
for (i = k * 2; i <= len; i *= 2)
{
if (i < len && a[i] < a[i + 1]) //比较俩孩子谁中较大的一个
i++;
if (a[0] >= a[i]) //若孩子小于跟,则跳出
break;
else //否则,孩子的数据填充到根节点
{
a[k] = a[i];
k = i;
}
}
a[k] = a[0]; //最后将存储的节点填回最终位置
}
//建立最大堆
void BuildMaxHeap(int a[], int len)
{
for (int i = len / 2; i >= 1; i--) //从非叶子结点开始
{
HeapAdjust(a, i, len);
}
}
2.堆排序
代码如下(示例):
//堆排序,交换头尾,调整
void HeapSort(int a[], int len)
{
BuildMaxHeap(a, len);
for (int i = len; i > 1; i--)
{
swap(a[i], a[1]); //交换最右下角的节点与根节点
HeapAdjust(a, 1, i - 1); //重新调整大根堆
}
}
总结
简单来说,堆排序就是利用大根堆的根节点一定是此时树中最大的数据,将其换出,排在数据末尾。然后进入下一次循环,换出次大的节点,直至结束。
堆排序属于选择排序。