【算法】堆排序

来源:互联网 发布:yishop 源码 编辑:程序博客网 时间:2024/06/04 19:48

堆,是一种完全二叉树,分为最大堆最小堆(或者叫“大根堆” “小根堆”)。
最大堆即:每个父节点元素都大于等于其所有子节点元素。最小堆同理。

堆排序的第一步便是构造堆。构造堆有两个重要方法,即sink(下沉)swim(上浮)

sink & swim

假设目前又一个有序的最大堆,然后在index处插入一个元素,堆变的无序,为了使堆恢复有序,就要用到sinkswim方法,代码实现如下:

【声明】这里假设堆顶为0,所以第k个节点的子节点为2 * k + 12 * k + 2,父节点为(k % 2 == 0) ? ((k - 1) / 2) : (k / 2)

// 堆排序辅助方法————下沉(小元素下沉)void sink(int *arr, int index, int len){    int i;    // index 的子节点为 (2 * index + 1) 和 (2 * index + 2)    while(2 * index + 1 <= len - 1){        i = 2 * index + 1;        // 和最大的子节点交换        if((i + 1 <= len - 1) && (arr[i] <= arr[i + 1]))            i++;        if(arr[index] >= arr[i])            break;        exchange(arr, index, i);        index = i;    }}

方法sink的主要思想就是,比较父节点和子节点,并把该元素和最大的子节点交换,一直“沉”到适当的位置,这里是最大堆,所以把小元素“下沉”

// 堆排序辅助方法————上升(大元素上升)void swim(int *arr, int index, int len){    int i;    while (index > 0) {        i = (index % 2 == 0) ? ((index - 1) / 2) : (index / 2); // 父节点        if(arr[index] <= arr[i])            break;        exchange(arr, index, i);        index = i;    }}

swim则和sink相反,比较子节点和父节点,一直“浮”到适当的位置,这里是最大堆,所以把大元素“上浮”

构造堆

构造堆即通过sinkswim方法。

【注意】构造堆时,如果用sink法,就要从数组的一半位置向前迭代;如果用swim法就要从堆第二层(即第二个元素)开始向后迭代。

// sink构建最大堆for(int i = len / 2 - 1; i >= 0; i--)    sink(arr, i, len);
// swim构建最大堆for(int i = 1; i < len; i++)    swim(arr, i, len);

堆排序

堆排序第一步即是构造堆。构造堆后,即从最后一个元素开始,交换堆顶和堆的最后一个元素,因为是最大堆,所以此时堆的最后一个元素应为最大数,然后除去该数,即堆的大小减一,把堆顶sink下来,这样大小减一之后的堆就又变为有序的了。代码实现如下:

// 堆排序void heapSort(int *arr, int len){    // sink构建最大堆    for(int i = len / 2 - 1; i >= 0; i--)        sink(arr, i, len);    // 下沉排序    for(int i = len - 1; i >= 0; i--){        exchange(arr, 0, i); // 交换堆顶和最后一位,最后一位即为最大数        sink(arr, 0, i); // 将堆的大小减一,然后将换到堆顶的数”沉“下去    }}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小鸡仔不吃食了怎么办 小鸡的腿瘸了怎么办 在境外住酒店钱被偷了怎么办 一加6屏幕辣眼睛怎么办 棉质衣服皱了怎么办 洗完衣服皱了怎么办 穿衬衫袖子很皱怎么办 洗完衣服有褶皱怎么办 麻料裤子容易皱怎么办 苹果手机邮件删了怎么办 飞猪12306登录不上怎么办 邮箱被别人绑定12306怎么办 白名单一个地址也没怎么办 12306忘记用户名和密码怎么办 12306忘了用户名和密码怎么办 12306注册后忘了密码怎么办 12306帐号忘了密码怎么办 12306忘了密码和手机号怎么办 12306账号密码邮箱忘了怎么办 注册12306账号没有邮箱怎么办 12306忘了用户名和邮箱怎么办 12306忘记用户名和邮箱怎么办 12306证件号码已被注册怎么办 12306忘记手机号和邮箱怎么办 发邮件被对方服务器退回怎么办 铁路12306显示已注册怎么办 qq密码太长输不进去怎么办 淘宝买家收货地址填写不全怎么办 护士电子注册账户未激活怎么办 您的邮件被退回怎么办 给国外发信被退怎么办 苹果8icloud满了怎么办 吃人参回奶了怎么办 邮箱被黑客黑了怎么办 传图识字有表格怎么办 手机qq收件箱图片打不开怎么办 腾讯企业邮箱一直被攻击怎么办 qq邮箱发送文件太大怎么办 苹果手机邮箱被删除了怎么办 亚马逊卖家登录邮箱被盗怎么办 邮箱名字被注册了怎么办