堆排序及算法分析.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
堆排序及算法分析 堆排序及算法分析 记得在学习数据结构的时候一味的想用代码实现算法,重视的是写出来的代码有一个正 确的输入,然后有一个正确的输出,那么就很满足了。从网上看了许多的代码,看了之后 貌似懂了,自己写完之后也正确了,但是不久之后就忘了,因为人脑在冋忆的时候,只依 稀记得代码屮的部分,那么的模糊,根木不能再次写出正确的代码,也许在第一次写的时 候是因为参考了别人的代码,看过之后人脑可以进行短暂的高清晰记忆,于是欺骗了我, 以为自12写岀來的,满足了成就感。可是代码是计算机识别的,而我们史喜欢文字,图 像。所以我们在学习算法的时候要注重算法的原理以及算法的分析,用文字,图像表达出 來,然后当需要用的吋候再将文字转换为代码。记忆分为三个步骤:编码,存储和检索, 就以学习为例,先理解知识,再归纳知识,最后巩固知识,为了以后的应用而方便检索知 识。 堆排序过程 堆分为人根堆和小根堆,是完全二叉树。犬根堆的要求是每个节点的值都不人于其父节 点的值,即A [PARENT [i]] = A[i]o在数组的非降序排序屮,需要使用的就是人根堆,因 为根据人根堆的要求可知,最人的值一定在堆顶。 既然是堆排序,白然需要先建立一个堆,而建堆的核心内容是调整堆,使二叉树满足堆 的定义(每个节点的值都不人于其父节点的值)。调堆的过程应该从最后一个非叶子节点 开始,假设有数组A二{1, 3, 4, 5, 7, 2, 6, 0} o那么调堆的过程如下图,数组下 标从0开始,A[3] = 5开始。分别与左孩子和右孩子比较人小,如果A[3]最人,则不用 调整,否则和孩子中的值最大的一个交换位置,在图1中是A[7] A[3] A⑻,所以 A[3]与A[7]对换,从图1.1转到图1.2。 所以建堆的过程就是 1: for ( i = headLen/2; i = 0; i++) 2: 3: do AdjustHcap(A, heapLen, i) 调堆:如果初始数组是非降序排序,那么就不需要调堆,直接就满足堆的定义,此为最 好情况,运行时间为?(1);如果初始数组是如图1.5,只有A[0] = 1不满足堆的定义, 经过与子节点的比较调整到图1.6,但是图1.6仍然不满足堆的定义,所以要递归调整, 一玄到满足堆的定义或者到堆底为止。如果递归调堆到堆底才结束,那么是最坏情况,运 行时间为0(h) (h为需要调整的节点的高度,堆底高度为0,堆顶高度为 floor(logn))。 建堆完成之后,堆如图1.7是个大根堆。将A[0] = 8与A[heaPLen-l]交换,然后 heapLen 减一,如图 2. 1,然后 AdjustHcap(A, heapLon-1, 0),女口图 2.2。如此交换堆的 第一个元素和堆的最后一个元素,然后堆的人小heapLen减一,对堆的人小为heapLen 的堆进行调堆,如此循环,直到heapl,en == 1时停止,最后得出结果如图3。 2:4:1:输入:zabery数组A,堆的长度hLen,以及需要调整的节点i 3:功能:调堆 2: 4: 1: 输入: zabery 数组A,堆的长度hLen,以及需要调整的节点i 3:功能: 调堆 */ 5: 6: void AdjustHcap(int A[], int hLen, int i) 7: { 8: int left = LeftChild(i); 〃节点 i 的左孩子 9: int right = RightChild(i) ; //节点 i 的右孩子节点 10: int largest = i; 11: int temp; 14: { 15: if (left hLen A[largest] A[left]) 16: { 17: largest = left;18: } 19: 20: if (right hLen Aflargest] A[right]) 21: { 22: largest = right; 23: 1 24: 25: if (i != largest) //如果最大值不是父节点 26: { 27: temp二A[largest]; //交换父节点和和拥育最人值的子节点交换 28: A[largest] = A[i]; 29: A[i] = temp; 30: 31: i = largest; //新的父节点,以备迭代调堆32: left. = LeftChild(i); 〃新的 子节点 33: right = RightChild(i); 34: j 35: else 36: { 37: break; 39: } 40: } 41: 42: /* 43:输入:数组A,堆的人小hLen 44:功能:建堆 45: */ 46: void Bui

文档评论(0)

ggkkppp + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档