堆排序

来源:互联网 发布:mac apache 关联php7 编辑:程序博客网 时间:2024/04/29 18:34

堆的定义:n个元素的序列{Kl,K2,…,Kn}当且仅当满足如下关系时,称之为堆。

(1) ki≤K2i且ki≤K2i+1 或(2)Ki≥K2i且ki≥K2i+1(1≤i≤  )

若将和此序列对应的一维数组(即以一维数组作为此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端节点的值均不大于(或不小于)其左右孩子节点的值。由此,若序列{Kl,K2,…,Kn}是堆,则堆顶元素(或完全二叉树的根)必为序列中n个元素的最小值(或最大值)。

序列{96,83,27,38,11,09}为堆,对应的二叉树如下图:



若在输出输出堆顶的最大值(最小值)之后,使得剩余的(n-1)个元素的序列重又建成一个堆,则得到n个元素中的次大(小)值。如此反复执行,便能的得到一个有序序列,这个过程称为堆排序

堆排序是一种树形选择排序,堆排序和直接选择排序的区别:

直接选择排序中,为了从R[1..n]中选出关键字最小的记录,必须进行n-1次比较,然后在R[2..n]中选出关键字最小的记录,又需要做n-2次比较。事实上,后面的n-2次比较中,有许多比较可能在前面的n-1次比较中已经做过,但由于前一趟排序时未保留这些比较结果,所以后一趟排序时又重复执行了这些比较操作。堆排序可通过树形结构保存部分比较结果,可减少比较次数。


实现堆排序需要解决两个问题:(1)如何由一个无序序列构造一个堆?(2)如何在输出堆顶元素后,调整剩余的元素成为一个新的堆?

因为构造初始堆需要用到堆得调整操作,所以我们先讨论“如何在输出堆顶元素后,调整剩余的元素成为一个新的堆”。

堆得调整(heapify):如图pic2所示的一个小根堆,假设输出堆顶元素之后,以堆中最后一个元素代替堆顶的元素,如图pic3所示。此时根节点的左右子树均为堆,则仅需自上自下向下调整即可。

首先以堆顶的元素和其左右子树的根结点的值进行比较,由于右子树的根节点小于左子树的根节点并且小于根节点的值。所以要将27和97交换,如图pic3种箭头所示。

由于97代替27之后破坏了右子树的堆的性质,则要将右子树进行核上述相同的调整,直至叶子节点。


pic2


pic3

我们称这个自堆顶至叶子节点的调整过程为“筛选”。

从一个无序序列构建堆得过程就是一个反复“筛选”的过程。若将此序列看成是一个完全二叉树,则最后一个非终端节点是第 个元素,由此“筛选”只需从第 个元素开始。

筛选函数heapify的算法如下:

/** * 调整a[i...j]使其成为一个大顶堆 * @param s表示需要调整的堆的堆顶的坐标 * @param m表示堆中索引的下限 * */protected void heapify(int[]a,int s,int m){int rc=a[s];for(int j=2*s;j<=m;j*=2){if(j<m&&a[j]<a[j+1])++j;if(rc>=a[j])break;a[s]=a[j];s=j;}a[s]=rc;}

构建初始堆的算法如下:

protected void buildheap(int[]a){int n=a.length/2;//最后一个非终端节点for(int i=n;i>=0;--i)this.heapify(a, i, a.length -1);}
堆排序:

public void heapsort(int[]a){this.buildheap(a);int temp=0;for(int i=a.length-1;i>0;i--){temp=a[0];a[0]=a[i];a[i]=temp;this.heapify(a, 0, i-1);}}




0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果升级后照片效果没了怎么办 360云盘个人云盘停止服务怎么办 小米手机账号掉了手机卡没了怎么办 百度网盘下载后不能注册怎么办 微信发出的文件无法撤回怎么办 微信群发错消息无法撤回怎么办 百度网盘登录要验证码怎么办 百度网盘备份记录怎么办能删掉 手机酷狗听歌耳机声音太小了怎么办 苹果6s微信通话声音变粗怎么办 千千静听多个列表合成一个了怎么办 别人用手机号注册了邮箱怎么办 微信身份信息验证未通过怎么办 快递地址填错了已经发到了怎么办 孩子威胁同学给她买东西吃怎么办 在超市买小孩米粉过期了怎么办 出口货物被海关扣了说仿牌怎么办 有一批仿牌被宁波海关查了怎么办 付了定金不想要车了怎么办 泥墙刮石灰上涂料现在刮腻子怎么办 月经最后一天同房了怎么办吃什么药 奶水太多了宝宝总是呛到了怎么办 婴儿刚吃完奶大量喷奶怎么办 我干活细致领导说我慢怎么办 怀孕初期吃了加明矾的粉皮怎么办 绿豆面黄豆面白面蒸馒头怎么办 画油画时把颜料染在衣服上怎么办 买的布衣柜少了一个管子怎么办 小2球刚好进2球怎么办 大2球刚好进2球怎么办 大球2进了2球怎么办 身上剩的几百块钱有掉了怎么办 刚买一天的手机电板有问题怎么办 宝宝长湿疹穿少了就感冒怎么办 照片跟视频被孩子删了怎么办 老公总是说一些不开心的话题怎么办 孩子沉迷手机篮球课不爱去怎么办 坐久了屁鼓会长疮怎么办 套胶的胶皮与海绵分离怎么办 换肾15天了沒尿怎么办? 妻子的绒癌怎么办?——急人!