堆排序

简介: 一.堆介绍堆,是一棵完全二叉树,根的值大于左右子树中所有结点的值,左右子树也是堆,除此之外,对其它元素之间的大小关系(如左右子树之间元素大小关系)没有要求。这是大根堆,如果把“大于”换成“小于“,就是小根堆,这里都以大根堆为例。由于堆是完全二叉树,所以可以用数组来模拟,在数据结构上算是比较简单。用数组模拟二叉树(当然也包括堆)的话,如果根节点的下标为0的话,则对于每个结点i,其左孩子下

一.堆介绍

堆,是一棵完全二叉树,根的值大于左右子树中所有结点的值,左右子树也是堆,除此之外,对其它元素之间的大小关系(如左右子树之间元素大小关系)没有要求。

这是大根堆,如果把“大于”换成“小于“,就是小根堆,这里都以大根堆为例。

由于堆是完全二叉树,所以可以用数组来模拟,在数据结构上算是比较简单。

用数组模拟二叉树(当然也包括堆)的话,如果根节点的下标为0的话,则对于每个结点i,其左孩子下标为2*i+1;其右孩子下标为2*i+2。

堆有两个基本操作:插入元素和删除元素。

插入: 将待插入元素添加到数组末尾,然后依次向上比较,如果该结点大于父亲节点,就与父节点交换,这样就构成局部大根堆,一直到该结点小于父节点位置,便完成了结点的插入操作。

删除: 要删除某元素,可以将数组的大小缩小一,然后用数组的末尾元素代替待删除元素,然后将缩小后的数组重新调整为堆,便完成了结点的删除操作。


二.堆排序的思想

将待排序区分为无序区和有序区,无序区在前,有序区在后。未排序前无序区为整个待排序区间,没有有序区。

排序的过程是,不断地将无序区构造成一个大根堆,这样无序区中的最大元素便被放置在了数组的最前面即根的位置,然后将无序区的第一个元素与最后一个元素交换,此动作将无序区的长度缩小一,将有序区的长度扩大一,即有序区前进一,无序区向前退一。然后将新的无序区(由于根节点的变化,此时很可能已经不是大根堆)重新调整为大根堆,等待下一次的交换。如此往复,不断地将无序区的最大元素添加到有序区的前面,同时缩小无序区,直到有序区占满待排序区为止。

这样,还剩下两个问题: 1.如何将一个交换后的无序区调整为大根堆; 2.如何在排序之前建立那个初始的大根堆。

而第二个问题是可以通过第一个问题的解决而解决的。这个稍后再谈,现在先看第一个问题。


三.将一个交换后的无序区调整为大根堆(自堆顶至叶子)


由于进行元素交换前,无序区是一个大根堆,即左子树和右子树都是大根堆,所以根节点变化后左右子树仍然都是大根堆,无序区里的最大元素一定在新根节点、左右子树的根节点这三个结点里。先存储新的根节点的值以待后用。如果新的根结点最大,说明已经是大根堆,调整完毕;否则比较左右子树根节点,找出较大的,它是无序区现存的最大元素,应该作为新的大根堆中的根,所以将此节点上调至根节点位置,接下来就只需要调整此结点原来所在的子树为大根堆即可(因为大根堆对左右子树之间元素的大小关系没有要求!)。

这是一个迭代的过程,当某一个需要调整的子树调整前就已经是大根堆(待调整的根节点比左右子树根节点都大)时,或者下标已经超出无序区范围时,迭代过程结束,无序区已经调整为大根堆。

这就是调整一个左右子树都为大根堆的完全二叉树为大根堆的过程。


堆排序实例

   首先,建立初始的堆结构如图:

  

  然后,交换堆顶的元素和最后一个元素,此时最后一个位置作为有序区(有序区显示为黄色),然后进行其他无序区的堆调整,重新得到大顶堆后,交换堆顶和倒数第二个元素的位置……

  

  重复此过程:

  

 

  最后,有序区扩展完成即排序完成:

  

 


四.建立初始大根堆


若数组下标范围为0~n,考虑到单独一个元素是大根堆,则从下标[n/2]开始的元素均为大根堆。于是只要从[n/2]-1开始,向前依次构造大根堆,这样就能保证,构造到某个节点时,它的左右子树都已经是大根堆(这就可以调用我们上面讨论的调整为大根堆的方法了)。一直到下标为0的结点,就完成了初始大根堆的建立。

堆排序用到的函数有两个:1个将左右子树都为大根堆的完全二叉树调整为大根堆的调整函数;1个反复调用此调整函数来进行排序的排序函数。


本质上,堆排序就是选择排序,每次选择当前无序区最大的放入有序区。

对于直接选择排序,选择的过程要进行遍历,一次选择过程的复杂度为O(n)。堆排序利用堆的性质和二叉树的结构使得每次选择的复杂度降低为O(logn),从而有效地改进了选择排序。


参考博文

http://blog.csdn.net/super_chris/article/details/4581900/

 

http://www.cnblogs.com/mengdd/archive/2012/11/30/2796845.html

 

 


本文出自 “点滴积累” 博客,请务必保留此出处http://tianxingzhe.blog.51cto.com/3390077/1658827

目录
相关文章
|
8月前
|
机器学习/深度学习 并行计算 算法
基于YOLOv8的5种玻璃缺陷识别(破裂/打胶/起霜/污染/未加工)(中英文双版) | 附完整源码与效果演示
本文介绍了一种基于YOLOv8的玻璃状况识别系统,该系统能够自动识别玻璃的五种常见缺陷:玻璃破裂、玻璃打胶、玻璃起霜、玻璃污染和玻璃未加工。通过采用先进的深度学习算法,实现了对玻璃产品的高精度、高效率检测,为工业生产提供了可靠的质量保障手段。
557 14
|
弹性计算 Linux 测试技术
阿里云ECS网络不稳定、访问丢包、延迟高怎么办?
若ECS服务器经常出现网络不稳定、延迟高等情况,针对不同情况,下面列出一些常用的解决方法供大家参考: 一、Linux实例 可以尝试先用如winmtr之类的工具,查看是服务端的丢包还是网际路由线路的丢包。
GEO
|
5月前
|
数据采集 人工智能 搜索推荐
2026年AI搜索优化三大趋势深度解读
2026年,AI重塑信息获取方式,“零点击搜索”兴起。GEO(生成式引擎优化)、AIVO(AI可见度优化)和AWVO(AI写作与网站内容优化)成为数字营销新核心。本文从市场规模、技术演进与实操策略三维度,解析三大趋势如何助力品牌抢占AI时代的“认知主权”与流量入口。
GEO
1609 0
|
5月前
|
人工智能 编解码 自然语言处理
阿里云AI产品与相关大模型活动参考:免费领Tokens,AI产品试用、大模型节省计划介绍
2026年截至目前阿里云AI产品及大模型服务的主要活动参考:AI订阅方面,Token Plan提供198-1398元/月三档套餐,Coding Plan Pro高级套餐200元/月限量发售;HappyHorse视频生成模型限时8折。免费试用提供超30款AI产品及7000万Tokens,涵盖Agent开发、图文生成、代码生成等。成本优化方面,全模型通用抵扣低至10元/月,AI通用型节省计划最高可享5.3折。此外还有"先用后返"优惠券活动,最高返200元。
|
8月前
|
运维 安全 网络安全
游戏开服遭遇DDoS后,如何通过IP数据定位攻击来源?
游戏DDoS溯源关键在分析ASN而非单个IP。通过批量查询攻击IP归属,锁定流量来自“抗投诉机房”或肉鸡池,快速形成攻击画像,为拦截和应急提供方向。
游戏开服遭遇DDoS后,如何通过IP数据定位攻击来源?
|
JavaScript 前端开发 定位技术
maptalks使用高德的瓦片如何进行配置?
maptalks使用高德的瓦片如何进行配置?
1590 12
|
SQL 数据可视化 关系型数据库
Quick BI 测评报告
Quick BI是阿里云推出的零代码可视化分析工具,适合个人开发者与小微团队使用。其核心优势在于轻量化启动(免费试用+按量付费)、多源接入(MySQL、MongoDB等)及敏捷分析能力(拖拽式仪表板)。实测显示,它支持智能CSV解析、语法高亮SQL编辑器和25+基础图表类型,具备图表联动交互功能。尽管缺少3D地图和自定义JS插件支持,但凭借低学习成本、OpenAPI扩展性以及移动端报表查看功能,Quick BI在个人项目展示、团队协作和轻量级数据分析中表现出色。不过,复杂计算需依赖SQL,移动端编辑和PDF导出存在局限性。
1271 3
|
开发框架 缓存 .NET
阿里云轻量应用服务器、经济型e、通用算力型u1实例怎么选?区别及选择参考
在阿里云目前的活动中,价格比较优惠的云服务器有轻量应用服务器2核2G3M带宽68元1年,经济型e实例2核2G3M带宽99元1年,通用算力型u1实例2核4G5M带宽199元1年,这几个云服务器是用户关注度最高的。有的新手用户由于是初次使用阿里云服务器,对于轻量应用服务器、经济型e、通用算力型u1实例的相关性能并不是很清楚,本文为大家做个简单的介绍和对比,以供参考。
|
数据采集 存储 SQL
连载:阿里巴巴大数据实践—数据开发平台
介绍MaxCompute和阿里巴巴内部基于MaxCompute的大数据开发套件,并对在数据开发过程中经常遇到的问题和相关解决方案进行介绍。
8592 0
连载:阿里巴巴大数据实践—数据开发平台
|
存储 C++ 索引
【C++打怪之路Lv9】-- vector
【C++打怪之路Lv9】-- vector
519 1