堆排序的基本思路

堆排序
虽然树还没弄懂,但是这个算法中用到的完全二叉树还是很容易懂的。
我们将堆排序的算法分为两部分,一部分是排序算法,另一部分是构造堆的算法。

void HeapAdjust(SqList* L, int s, int m)
{   // 调整堆内元素排序位置,将双亲结点和孩子结点中元素值最大的赋值给根结点
    int temp, j;
    temp = L->Array[s];
    for (j = 2 * s; j <= m; j *= 2)
    {   // 沿较大孩子结点向下筛选
        if (j < m && L->Array[j] < L->Array[j + 1])
            ++j; // j为关键字,记录孩子结点值较大的下标
        if (temp >= L->Array[j])
            break; // 双亲结点大于等于孩子结点,不进行交换
        L->Array[s] = L->Array[j];
        s = j;
    }
    L->Array[s] = temp;
}
void Heap_Sort(SqList* L)
{   
    int i;
    for (i = L->length / 2; i > 0; i--) {
        //把顺序表构建为一个大根堆
        HeapAdjust(L, i, L->length);
    }
    for (i = L->length; i > 1; i--)
    {
        swap(L, 1, i); // 将堆顶记录和当前未经排序子序列的最后一个记录交换
        HeapAdjust(L, 1, i - 1); // 重新将数组构建为大根堆,但不囊括树的i-1个元素
    }
}

构造堆有两种方式,一种大根堆,一种小根堆。我们以大根堆进行分析(小根堆不过是换几个符号):
在这里插入图片描述
每一步都是从双亲结点出发,找到它对应的左右孩子结点中最大值,如果比双亲结点的值大,进行交换,…,随后我们便得到一个大根堆。
在这里插入图片描述

依次取出大根堆根结点元素的值,随后我们便能得到一个从小到大的序列。

在堆排列中最重要的部分便是堆大根堆(小根堆)的构建,不断通过每次构建大根堆时把根结点元素取出(因为此时的根结点是树中的最大值)

但是堆排序堆原有的序列排序状态并不敏感,以至于没有最好和最坏的时间复杂度,无论什么时间复杂度都为O (nlgn)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值