堆排序时间复杂度_排序算法(五)--堆排序

  1. 堆排序

堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好平均时间复杂度为O(nlogn),它也是不稳定排序。

2. 堆

首先了解一下堆;堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:

340d27784c1279c3a237127022b0d583.png
大顶堆(左) 小顶堆(右)

同时,对堆中的结点进行编号(从上到下,从左到右,开始为0);以大顶堆为例映射到数组中就是: 90 , 70 , 80 , 60 , 10 , 40 , 50 , 30 , 20 ; 该数组从逻辑上讲就是一个堆结构。

堆的定义:

大顶堆 : arr[i] >= arr[2i+1] & arr[i] >= arr[2i+1]

小顶堆 : arr[i] <= arr[2I+1] & arr[i] <= arr[2i+1]

3. 堆排序的基本思想及步骤

基本思想将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

排序步骤:

(1) 将待排序的数组构建成一个大顶堆;

(2) 然后将最大值与末尾元素交换,并将剩余的数据重新调整为大顶堆;并重复次过 程,直到排序完成。

ff12b82a899f227a43117a17f3796db3.png
将最大值与末尾值交换,,并重新调整为大顶堆

263c731dcc95030f39fb89cbd15b6b78.png
同样将最大值与末尾数调整,并调整大顶堆

d3a9810e0ccf475e6dc52acbfa21ab2c.png
不断重复这个过程

d1ce4f6065fa4cb0d79cabc08a8a0de0.png
最终得到一个完整的有序序列

4. 时间复杂度分析

堆排序的运行时间主要是消耗在初始构建堆和重建堆时的反复筛选上。

在构建堆的过程中,因为是从完全二叉树从最下层最右边的非终端点开始构建,将它与其孩子进行比较和若有必要的互换,对于每个非终端点来说,其实最多进行两次比较和互换操作,因此整个构建堆的时间复杂度为O(n)。

在正式排序时,第 i 次取堆顶记录重建堆需要用O(logi)的时间(完全二叉树的某个结点到根结点的距离为

),并且需要取n-1次堆顶记录,因此,重建堆的时间复杂度为O(nlogn)。

所以总体来说,堆排序的时间复杂度为O(nlogn)。由于堆排序对原始记录的排序状态并不敏感,因此它无论是最好,最坏和平均时间复杂度均为O(nlogn)。

另外,由于初始构建堆所需要的比较次数较多,因此并不适合待排序个数较少的情况。


参考书籍 《大话数据结构》 -- 程杰 著. ——北京:清华大学出版社,2011.6
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值