常用排序2.docVIP

  1. 1、本文档共9页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
常用排序2

堆排序 1 什么是堆 ???????首先堆是一种数据结构,是一棵完全二叉树且满足性质:所有非叶子结点的值均不大于或均不小于其左、右孩子结点的值,如下是一个堆得示例: ??????????????? ?????????98,95;83,81;52?? 由此发现非叶子结点的值均不小于左右孩子结点的值,所以这是个大顶堆,即堆顶的值是这个堆中最大的一个。 ?????这个堆可以看成是一个一维数组A[6]={9,8,5,3,1,2},那么相应的这个数组需满足性质:A[i]=A[2*i] A[i]=A[2*i+1] 。其中A[i]对应堆中的非叶子结点,A[2*i]和A[2*i+1]对应于左右孩子结点。并且最后一非叶子结点下标为[n/2]向下取整。 ?????????为什么是[n/2]向下取整呢?在这里我简单的说明一下:设n1表示完全二叉树中有一个孩子的结点,n2表示表示完全二叉树中有两个孩子的结点,d表示非叶子结点的个数,那么总的结点个数:n=n1+2*n2+1。 ??????? (1)当n为奇数时,n1=0,n2=(n-1)/2,d=n2+n1=(n-1)/2 ????????(2)当n为偶数时,n1=1,n2=n/2-1,d=n2+n1=n/2 ????????? 由此可以看出d=[n/2]向下取整. ????????? 2?筛选法调整堆 ????????(1)引出: ????????现给定一个大顶堆:? 即:A[6]={9,8,5,3,1,2},如果我们稍做破坏,把9跟2互换,同时把a[6]这个结点从堆中去掉,于是得到下面这个完全二叉树: ??????? ? A[5]={2,8,5,3,1} 显然它不是一个堆,那我们怎么把它调整为一个堆呢?首先观察,我们只是改变了根结点的值,所以根结点左、右子树均是大顶堆。其次思考,既然是根结点可能破坏了堆的性质,那我们就可以把根结点往下沉,让最大值上浮,即比较根结点和左、右孩子的值,若根结点的值不小于孩子结点的值,说明根结点并没有破坏堆的性质,不用调整;若根结点的值小于左右孩子结点中的任意一个值,则根结点与孩子结点中较大的一个互换,互换之后又可能破坏了左或右子树的堆性质,于是要对子树进行上述调整。这样的一次调整我们称之为一次筛选。 ??????(2)代码: ??????? [cpp]?view plaincopy span?style=font-size:18px;//调整堆,保持大顶堆的性质,参数i指向根结点?? void?maxHeap(int?*a,int?n,int?i)?? {?? ????//left、right、largest分别指向?? ????//左孩子、右孩子、{a[i],a[left]}中最大的一个?? ????int?left,right,largest;?? ????largest=left=2*i;?? ????if(leftn)?? ????????return;?? ????right=2*i+1;?? ????if(right=n??a[right]a[left]){?? ????????largest=right;?? ????}?? ????if(a[i]a[largest]){//根结点的值不是最大时,交换a[i],a[largest]?? ????????a[i]=a[i]+a[largest];?? ????????a[largest]=a[i]-a[largest];?? ????????a[i]=a[i]-a[largest];?? ????????//自上而下调整堆?? ????????maxHeap(a,n,largest);?? ????}?? }/span?? (3)示例 以这个完全二叉树为 例?:??????? A[5]={2,8,5,3,1} 第一次筛选:2和8交换 ?? A[5]={8,2,5,3,1} 第二次筛选:2和3交换 ?? A[5]={8,3,5,2,1} 筛选完毕,得到大顶堆A[5]={8,3,5,2,1}。 (4)时间代价分析 每一次筛选的过程就是调用一次maxHeap函数,需要的时间是O(1)。那么要执行多少次筛选呢?从上述中可以看出,每一次筛选根结点都往下沉,所以筛选次数不会超过完全二叉树的深度:([log2n]向下取整+1),其中n为结点个数,2为底数,即时间复杂度为O(log2n) ?为什么n个结点的完全二叉树的深度是([log2n]向下取整+1)呢?这里给出简单的说明: ???????? 深度为h的完全二叉树至多有2^h-1个结点,即2^(h-1)=n2^h,推出h-1=log2nh;由于h是一个整数,所以h=[l

文档评论(0)

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

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

1亿VIP精品文档

相关文档