- 1、本文档共73页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
49 38 65 97 76 13 27 49 38 65 13 27 38 13 13 M 76 M 27 27 由于含有n个子结点的完全二叉树的深度为log2n+1,则在树形选择排序中,除了最小数值之外,每选择一个次小数仅需要进行log2n次比较,因此,它的时间复杂度为O(nlogn)。但是,这种排序方法尚有辅助存储空间较多、和“最大值”进行多余比较等缺点。为了弥补,威洛姆斯(J. willioms)在1964年提出了另一种形式的选择排序——堆排序。 堆排序 堆的概念:高有n个元素的序列{k1,k2, …,kn},当且仅当满足下述关系之一,称这为堆。 如果堆中根结点的排序码最小,则称为小根堆;如果堆中根结点的排序码最大,则称为大根堆。 堆排序的思想是:首先设法把原始序列构造成一个堆,使得n个元素的最大值处于序列的第一个位置;然后交换序列第一元素(最大值元素)与最后一个元素。再把序列的前n-1个元素组成的子序列构成一个新堆,重复以上步骤,最终整个序列成为有序序列。 堆排序的关键是:(1)如何将一个无序序列建成一个堆; (2)如何把“去掉”了最大值元素后的序列 调整剩余元素为一个新的堆。 构造初始堆是指把整个记录从R1到Rn调整为一个大根堆。完全二叉树中,所有序号 in/2的结点都是叶结点,以这些结点为根的子树均已是堆,只需依次将以序号 n/2,n/2-1, …,1结点为根的子树调整为堆即可。 用筛选法为以 Ri为根的完全二叉树建堆,若Ri的左右子树都是堆,可以把 Ri与其左右子树根结点 R2i+1,R2i+2中最大者交换位置。若交换位置后破坏了子树的堆特性,则再对这棵子树重复交换过程,直到以Ri 为根结点的子树成为堆。 Void heapAdjust(DataType R[], int s,int t) { int i,j; DataType rc; rc=R[s];i=s; for(j=2*i;j=t;j=2*j) { if(jt R[j].keyR[j+1].key) j=j+1; if(rc.keyR[j].key) break; R[i]=R[j]; i=j; } R[i]=rc; } 05 61 59 48 19 11 26 15 01 05 rc i j 61 i j 48 i j 15 05 void HeapSort( DataType R[],int n) { int I; for( i=n/2;i0;i--) HeapAdjust(R,i,n); for(i=n;i1;i--) { R[0]=R[1]; R[1]=R[i]; R[i]=R[0]; HeapAdjust(R,1,i-1); } } 初始序列为26,5,77,1,61,11,59,15,48,19,请用堆排序法排序。 (1)初始完全二叉树 (2)调整序号为5的结点 (3)调整序号为4的结点 (4)调整序号为3的结点 (5)调整序号为2的结点 (6)调整序号为1的结点 (7)结点77与结点5互换 (8)重建堆 (9)结点61与结点1互换 (10)重建堆 (11)结点59与结点05互换 (12)重建堆 (13)结点48与结点1互换 (14)重建堆 (15)结点26与结点1互换 (16)重建堆 (17)结点19与结点5互换 (18)重建堆 (19)结点15与结点1互换 (20)重建堆 堆排序的时间耗费主要在构造初始堆,以及排序中去掉最大元素后重建堆两部分。 初始建堆共调用HeapAdjust函数 n/2次,每次将一个Ri(in/2)为根的子树树调整为堆。个结点的完全二叉树,其深度 的结点层数依次为:0,1,1,2,2,2,…,h-1。 个,以它为根的子树深度为h-m。 第m层上结点数最多为 HeapAdjust算法的每层上与两个子女和排序码值进行比较,所以在m层上结点执行初始建堆最多比较2(h-m)次,第m层所有子树建堆最多比较次数为 第一部分 初始建堆总的比较次数为 排序中每去掉最大元素后需要
文档评论(0)