[MIT6.006] 4. Heaps and Heap Sort 堆,堆排序
第4节课仍然是讲排序,但介绍的是一种很高效的堆排序。
在编程过程中,有时候会需要进行extrat_max的操作,即从一个数列里挨个抽取最大值并将其它从原数列中移除。而排序问题也可以看作是一个extract_max的行为,不断的从原始数列中抽取最大值并进行移除,这样挨个抽取的最大值输出后能得到一个降序的数列。为了实现该排序思路,堆排序被提了出来,首先我们的了解下堆的概念:
堆(Heap):一个数列被可视化为一个近似完全二叉树,这个树则为堆。如下图所示:

在堆的基础上,有分:最大堆和最小堆。
- 最大堆(Max-Heap):某节点的key ≥ 子节点的key。
- 最小堆(Min-Heap):某节点的key ≤ 子节点的key。
为了构建最大堆,有个操作叫max_heapify,它就在子树根(subtree's root)上纠正违反最大堆属性(某节点的key ≥ 子节点的key),下图展示了一个max_heapify的例子。
从上图可以看出,倒数第二行(即n/2个元素)是向下比较一次,倒数第三行(n/4个元素)是向下比较两次,...。(问:为什么倒数第三行是向下比较两次?答:用上图的例子说明,如果倒数第三行的4需要修正最大堆属性,和14换,这是比较一次,而换后的4与8不合最大堆属性,所以又换了一次,这是第二次比较。加起来就两次比较)。那么n/2^k个元素的向下比较了k次,所以MAX_HEAPIFY(A, 跟节点)的复杂度为Οlog2n(n/2^k≤1)。
对无序数列构建一个大堆堆的方法如下图所示,是以bottom-up的方式,从i=n/2结点位置依次向上遍历进行max_heapify操作。
基于以上的方法,我们可以实现堆排序:
- 将无序A数列构建一个堆。(Ο(n))
- 将堆进行max_heapify修正为最大堆。(Ο(log2n))
- 找到最大值元素A[1],即当前最大堆的跟节点。(Ο(1))
- 将A[1]和堆最后的元素A[n]进行交换。(Ο(1))
- 将元素A[n]撤出堆,减少堆大小。(Ο(1))
- 现在堆也许会违背最大堆属性,因此重复2-5步骤。(有n steps)
由于A(n)不断撤出,堆大小也会不断改变。复杂度不再是Ο(n + nlog2n) - 其中n为建堆,nlog2n中的第一个n是n steps,而第二个log2n是max_heapify,因为堆大小不断减小时,n和n都在同步减少,这样nlog2n实际上应为n,最后堆排序的时间复杂度为Ο(n)(Ο(n+n)=Ο(2n)=Ο(n))。
下图为一个堆排序的例子:
[MIT6.006] 4. Heaps and Heap Sort 堆,堆排序的更多相关文章
- PAT Advanced 1098 Insertion or Heap Sort (25) [heap sort(堆排序)]
题目 According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and ...
- [MIT6.006] 6. AVL Trees, AVL Sort AVL树,AVL排序
之前第5节课留了个疑问,是关于"时间t被安排进R"的时间复杂度能不能为Ο(log2n)?"和BST时间复杂度Ο(h)的关系.第6节对此继续了深入的探讨.首先我们知道BST ...
- 【算法】堆排序(Heap Sort)(七)
堆排序(Heap Sort) 堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法.堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父 ...
- 1098 Insertion or Heap Sort (25 分)(堆)
这里的第二序列相当于是排序还没拍好的序列 对于第二个样例的第二个序列其实已经是大顶堆了 然后才进行的堆排序 知道这个就好做了 #include<bits/stdc++.h> using n ...
- [数据结构]——堆(Heap)、堆排序和TopK
堆(heap),是一种特殊的数据结构.之所以特殊,因为堆的形象化是一个棵完全二叉树,并且满足任意节点始终不大于(或者不小于)左右子节点(有别于二叉搜索树Binary Search Tree).其中,前 ...
- [Unity][Heap sort]用Unity动态演示堆排序的过程(How Heap Sort Works)
[Unity][Heap sort]用Unity动态演示堆排序的过程 How Heap Sort Works 最近做了一个用Unity3D动态演示堆排序过程的程序. I've made this ap ...
- 09-排序3 Insertion or Heap Sort
和前一题差不多,把归并排序换成了堆排序.要点还是每一次排序进行判断 开始犯了个错误 堆排序该用origin2 结果一直在排序origin ,误导了半天以为是逻辑错误...一直在检查逻辑 建立最大堆 排 ...
- 堆排序 Heap Sort
堆排序虽然叫heap sort,但是和内存上的那个heap并没有实际关系.算法上,堆排序一般使用数组的形式来实现,即binary heap. 我们可以将堆排序所使用的堆int[] heap视为一个完全 ...
- 数据结构 - 堆排序(heap sort) 具体解释 及 代码(C++)
堆排序(heap sort) 具体解释 及 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 堆排序包括两个步骤: 第一步: 是建立大顶堆(从大到小排 ...
随机推荐
- Prometheus 系列开篇:为什么要学 Prometheus ?
「Prometheus 系列开篇:为什么要学 Prometheus ?」首发于[陈树义]公众号,点击跳转到原文https://mp.weixin.qq.com/s/HCS6X3l6nVBw_hAnd6 ...
- SpringBoot+单机redis
spring boot-redis集成 看教程来的,看起来很简单,但是集成后发现启动失败? WARN 2556 --- [ restartedMain] ationConfigEmbeddedWebA ...
- chrome(谷歌)登录失败解决方案
相信有很多小伙伴和我一样,同步chrome的收藏夹,这样也便于随时可以查看自己收藏的网址.但是同步文件,必须先要登录chrome账号,登录chrome账号时,总是会报黄页,或者一直加载不出来.接下来, ...
- C语言的污垢,一个能污染内存的神秘操作!神级坑位再现~
本文目的是为了更好的理解指针和内存管理 背景 我们定义一个变量A,修改另外一个一个变量B,导致A的值被修改,我们称它为内存污染. 案例 如下程序,正常的预期输出应该是:97 98 256 ,但正确的结 ...
- 分布式事务说的的2PC、3PC、TCC是啥
目录 2PC(Two Phase Commit) 3PC(Three Phase Commit) TCC(Try-Confirm-Cancel) 2PC(Two Phase Commit) 顾名思义, ...
- Linux入门到放弃之五《用户管理》
用户管理 1.创建新用户user123,以此用户登陆系统,在tmp下创建文件test123: 2.修改test123文件的所有者为root,所属组也为root: 需要先切换为root用户 3.修改te ...
- Redis分布式锁及分区
以下内容是翻译的官网文档RedLock和分区部分,可以简单了解分布式锁在redis如何实现及其方式 redis分区的方法 redis实现的分布式锁RedLock算法,分布式锁,即在多个master上获 ...
- zctf2016_note2:一个隐蔽的漏洞点挖掘
代码量挺大的,逆起来有难度 功能挺全,啥都有 main函数 add函数,有heaparray并且无pie保护,考虑unlink show函数,可以泄漏地址用 edit函数,有两种edit方式 dele ...
- SpringMVC+Spring+MyBatis个人技术博客源码
项目描述 Hi,大家好,又到了源码分享时间啦,今天我们分享的源码一个<个人技术博客>,该博客是基于SSM实现的一个个人博客系统,适合初学SSM和个人博客制作的同学学习.有了这个源码,直接买 ...
- 【应用服务 App Service】App Service证书导入,使用Key Vault中的证书
问题描述 正常情况下,如果需要为应用服务安装SSL证书,可以在证书准备好的情况,通过门户上传即可,详细步骤可以参考微软官方文档(在 Azure 应用服务中添加 TLS/SSL 证书:https://d ...