版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、3.3.3 堆排序(Heap Sort),1、堆的定义,n个关键字序列Kl,K2,Kn称为堆,当且仅当该序列满足如下性质(简称为堆性质): (1) Ki K2i 且 Ki K2i+1 (小顶堆) 或 (2) Ki K2i 且 Ki K2i+1 (大顶堆) (1in/2),若将此序列所存储的向量R1.n看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树: 树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。,(大顶堆),(小顶堆),(小根堆) (最小堆),(大根堆) (最大堆),例:有序列T1=(08, 25, 49, 46, 58, 67)和序列T2
2、=(91, 85, 76, 66, 58, 67, 55),判断它们是否 “堆”?,逻辑结构:,存储结构:,2、大根堆和小根堆,根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆。 根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆。,注意: 堆中任一子树亦是堆。 以上讨论的堆实际上是二叉堆(Binary Heap),类似地可定义k叉堆。,3、堆的特点,堆排序(HeapSort)是一树形选择排序。 堆排序的特点是:在排序过程中,将Rl.n看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系,在当前无序区中选择关键字最大(或最
3、小)的记录。,4、堆排序与直接插入排序的区别,直接选择排序中,为了从R1.n中选出关键字最小的记录,必须进行n-1次比较,然后在R2.n中选出关键字最小的记录,又需要做n-2次比较。事实上,后面的n-2次比较中,有许多比较可能在前面的n-1次比较中已经做过,但由于前一趟排序时未保留这些比较结果,所以后一趟排序时又重复执行了这些比较操作。 堆排序可通过树形结构保存部分比较结果,可减少比较次数。,5、堆排序,堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单。,(1)用大根堆排序的基本思想, 先将初始文件R1.n建成一个大
4、根堆,此堆为初始的无序区 再将关键字最大的记录R1(即堆顶)和无序区的最后一个记录Rn交换,由此得到新的无序区R1.n-1和有序区Rn,且满足 R1.n-1.keys Rn.key 由于交换后新的根R1可能违反堆性质,故应将当前无序区R1.n-1调整为堆。然后再次将R1.n-1中关键字最大的记录R1和该区间的最后一个记录Rn-1交换,由此得到新的无序区R1.n-2和有序区Rn-1.n,且仍满足关系R1.n-2.keysRn-1.n.keys,同样要将R1.n-2调整为堆。 直到无序区只有一个元素为止。,(2)大根堆排序算法的基本操作, 初始化操作:将R1.n构造为初始堆; 每一趟排序的基本操作
5、:将当前无序区的堆顶记录R1和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。,注意:只需做n-1趟排序,选出较大的n-1个关键字即可以使得文件递增有序。用小根堆排序与利用大根堆类似,只不过其排序结果是递减有序的。堆排序和直接选择排序相反:在任何时刻,堆排序中无序区总是在有序区之前,且有序区是在原向量的尾部由后往前逐步扩大至整个向量为止。,(3)堆排序的算法,void HeapSort(SeqIAst R) /对R1.n进行堆排序,不妨用R0做暂存单元 int i; BuildHeap(R); /将R1-n建成初始堆for(i = n; i 1;i-) /对当前无序区R1.i
6、进行堆排序,共做n-1趟。 R0 = R1; /将堆顶和堆中最后一个记录交换 R1 = Ri; Ri = R0; Heapify(R, 1, i-1);/将R1.i-1重新调整为堆,仅有R1可能违反堆性质 ,(4)BuildHeap和Heapify函数的实现,Heapify函数思想方法 每趟排序开始前Rl.i是以R1为根的堆,在R1与Ri交换后,新的无序区R1.i-1中只有R1的值发生了变化,故除R1可能违反堆性质外,其余任何结点为根的子树均是堆。因此,当被调整区间是Rlow.high时,只须调整以Rlow为根的树即可。 筛选法调整堆 Rlow的左、右子树(若存在)均已是堆,这两棵子树的根R2
7、low和R2low+1分别是各自子树中关键字最大的结点。若Rlow.key不小于这两个孩子结点的关键字,则Rlow未违反堆性质,以Rlow为根的树已是堆,无须调整;否则必须将Rlow和它的两个孩子结点中关键字较大者进行交换,即Rlow与Rlarge(Rlarge.key=max(R2low.key,R2low+1.key)交换。交换后又可能使结点Rlarge违反堆性质,同样由于该结点的两棵子树(若存在)仍然是堆,故可重复上述的调整过程,对以Rlarge为根的树进行调整。此过程直至当前被调整的结点已满足堆性质,或者该结点已是叶子为止。上述过程就象过筛子一样,把较小的关键字逐层筛下去,而将较大的关
8、键字逐层选上来。因此,有人将此方法称为筛选法。,BuildHeap的实现要将初始文件Rl.n调整为一个大根堆,就必须将它所对应的完全二叉树中以每一结点为根的子树都调整为堆。显然只有一个结点的树是堆,而在完全二叉树中,所有序号in/2的结点都是叶子,因此以这些结点为根的子树均已是堆。这样,我们只需依次将以序号为n/2,n/2 -1,1的结点作为根的子树都调整为堆即可。,大根堆排序实例演示,(5)堆排序算法分析,堆排序的时间,主要由建立初始堆和反复重建堆这两部分的时间开销构成,它们均是通过调用Heapify实现的。 堆排序的最坏时间复杂度为O(nlgn)。堆排序的平均性能较接近于最坏性能。 由于建
9、初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。 堆排序是就地排序,辅助空间为O(1)。 它是不稳定的排序方法。,基数排序: 是一种借助“多关键字排序”的思想来实现“单关键字排序”的内部排序算法(即:用关键字不同的位值进行排序。 )。 要讨论的问题: 1. 什么是“多关键字”排序?实现方法? 2. 单逻辑关键字怎样“按位值”排序?,多关键字排序的实现方法通常有两种: 1)最高位优先法MSD (Most Significant Digit first) 2)最低位优先法LSD (Least Significant Digit first),3.4 基数排序(Radix Sort),
10、举例: 以扑克牌排序为例。每张扑克牌有两个“排序码”:花色和面值。其有序关系为: 花色: 面值:2 3 4 5 6 7 8 9 10 J Q K A 如果我们把所有扑克牌排成以下次序: 2, , A, 2, , A, 2, , A, 2, , A 这就是多关键字排序。,例:对一副扑克牌该如何排序? 答:若规定花色为第一关键字(高位),面值为第二关键字(低位),则使用MSD和LSD方法都可以达到排序目的。 MSD方法的思路:先设立4个花色“箱”,将全部牌按花色分别归入4个箱内(每个箱中有13张牌);然后对每个箱中的牌按面值进行插入排序(或其它稳定算法)。 LSD方法的思路:先按面值分成13堆(每
11、堆4张牌),然后对每堆中的牌按花色进行排序(用插入排序等稳定的算法)。,想一想:用哪种方法更快些?,2. 单逻辑关键字怎样“按位值”排序? 思路:设n 个记录的序列为:V0, V1, , Vn-1 ,可以把每个记录Vi 的单关键码 Ki 看成是一个d元组(Ki1, Ki2, , Kid),则其中的每一个分量Kij ( 1 j d ) 也可看成是一个关键字。,注1: Ki1最高位关键字,Kid最低位关键字;Ki共有d位,可看成d元组; 注2: 每个分量Kij (1 j d ) 有radix种取值,则称radix为基数。,(9, 8, 4),(0, 1, , 9),(a, b, , z),(d,
12、i, a, n),例1:关键码984可以看成是 3 元组;基数radix 为 10 。,例2:关键码dian可以看成是 4 元组;基数radix 为 26 。,初始状态,第一趟“分配”之后的结果,第一趟“收集”之后的结果,采用“分配”与“收集”的方法实现基数排序。,第二趟“分配”之后的结果,第二趟“收集”之后的结果,对由顺序表表示法存储的记录进行基数排序可利用“计数”和“复制”的操作实现。,记录数组A,记数数组count (个位情况),累加结果count,(a)初始状态和对“个位数”计数的结果,累加结果count,记录数组B,记数数组count (十位情况),(b)计数器的累加结果和记录“复制
13、”后的状态,记数数组count (十位情况),累加结果count,记录数组A,(c)对“十位数”计数和“复制”和记录“复制”后的状态,基数排序实例演示,【基数排序算法 】 void RadixSort( SqList /排序后的结果在C中,复制至L.r中 / while / RadixSort,【一趟基数排序算法 】 void RadixPass( RcdType A, RcdType B, int n, int i ) / 对数组A中记录关键字的第i位计数,并按计数数组count的值 / 将数组A中记录复制到数组 B中 for ( j=0; j=0; -k ) / 从右端开始复制记录 j =
14、 Ak.keysi; B countj-1 = Ak; countj-; / for / RadixPass,时间复杂度: O(dn)(d趟基数排序,每趟对n个记录进行“计数”和“复制”)。 空间复杂度:O(n),因为有分组,故此算法需递归实现。,思考:是借用MSD方式来排序呢,还是借用LSD方式?,方法1(MSD):原始序列:32, 13, 27, 32*, 19, 33 先按高位Ki1 排序:(13, 19), 27, (32, 32*,33) 再按低位Ki2 排序 : 13, 19 , 27, 32, 32*, 33,方法2(LSD): 原始序列: 32, 13, 27, 32*, 19
15、 ,33 先按低位Ki2排序: 32, 32*, 13, 33, 27, 19 再按高位Ki1排序: 13, 19 , 27, 32, 32*, 33,无需分组,易编程实现!,例:初始关键字序列T=(32, 13, 27, 32*, 19,33),请分别用MSD和LSD进行排序,并讨论其优缺点。,一、时间性能,1. 平均的时间性能,时间复杂度为 O(nlogn):快速排序、堆排序和归并排序 时间复杂度为 O(n2):直接插入排序、起泡排序和简单选择排序 时间复杂度为 O(n): 基数排序,2. 当待排记录序列按关键字顺序有序时 直接插入排序和起泡排序能达到O(n)的时间复杂度; 快速排序的时间性能蜕化为O(n2),3. 简单选择排序、堆排序和归并排序的时间性能不随记录序列中关键字的分布而改变。,3.5 各种排序方法的比较,二、空间性能,空间性能指的是排序过程中所需的辅助空间大小,1. 所有的简单排序方法(包括:直接插入、起泡和简单选择) 和堆排序的空间复杂度为O(1);,2. 快速排序为O(logn),为递归程序执行过程中,栈所需的辅助空间;,3. 归并排序和基数排序所需辅助空间最多,其空间复杂度为 O(n);,三、排序方法的稳定性能,1. 稳定的排序方法指的是,对于两个关键字相等的记录,它们在序列中的相对位置,在排序之前和经过排序之后,没有改变。,2
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年环保行业废旧电池回收利用报告
- 2026年山西财贸职业技术学院单招综合素质考试题库带答案详解(模拟题)
- 2026年广东理工职业学院单招综合素质考试题库附参考答案详解(模拟题)
- 2026年广东省外语艺术职业学院单招职业倾向性考试题库及参考答案详解1套
- 2026年山西省阳泉市单招职业适应性考试题库带答案详解(模拟题)
- 2026年广东南华工商职业学院单招职业倾向性考试题库附答案详解(黄金题型)
- 2026年广州城建职业学院单招综合素质考试题库含答案详解(夺分金卷)
- 2026年山西药科职业学院单招职业倾向性测试题库附参考答案详解(能力提升)
- 2026年山西运城农业职业技术学院单招职业倾向性测试题库附参考答案详解(基础题)
- 2026年广州城市职业学院单招职业倾向性测试题库含答案详解(能力提升)
- 定陶区287.5MW风力发电项目配套220kV升压站工程报告表
- 实习护士第三方协议书
- 水利工程施工安全生产管理工作导则
- 民宿委托经营管理协议合同书
- 四川省森林资源规划设计调查技术细则
- 《论文写作基础教程》课件
- 2024-2025学年鲁教版(五四学制)(2024)初中英语六年级下册(全册)知识点归纳
- 化工总控工-仪表自动化知识考试题库
- 大大服装厂 SOP 作业指导书
- 【课件】书画同源+课件-2024-2025学年高中美术人教版+(2019)+选择性必修2+中国书画
- GB/T 19973.2-2025医疗产品灭菌微生物学方法第2部分:用于灭菌过程的定义、确认和维护的无菌试验
评论
0/150
提交评论