一、堆排序

要弄明白堆排序,我们首先要明白什么叫堆,堆可以理解为把一个完全二叉树放到一个数组里。也就是说这个完全二叉树按照层数从根节点那层开始被削成一层一层的往数组里面依次摆放。

我们不难得到这个关系,如图,如果有一个下标为n的节点kn,因为数组是从0开始所以由于完全二叉树的性质,他的左孩子的下标就应该是2(n+1)-1,即2n+1。他的右孩子在左孩子右面的第一个位置,就是2n+2。

图源:B站up我是AXin

那么我们可以通过二叉树逻辑结构去构建一个大顶堆(也就是每棵子树的父节点都比他们两个孩子的最大值大),所以我们可以得到一个大顶堆的根结点,因为他是所有父节点的父节点的父节点。。。所以他的值应该是最大的。等等,我们可以得到最大值,这有点像选择排序,对吧?所以我们可以用选择排序的思路,把无序组的最大值依次排列到在数组后部的有序组里面,直到无序组里面的元素个数为0。下面提供两种实现方式:

1.

void heap(int arr[], int x, int n) {int dad = x, son = x * 2 + 1;
//让父节点等于他们孩子的最大值if (son < n && arr[dad] < arr[son])dad = son;if (son + 1 < n && arr[dad] < arr[son + 1])dad = son + 1;if (dad != x)//交换过{swap(arr[x], arr[dad]);//swap函数上一篇文章有讲heap(arr, dad, n);}
}
void Heap_sort(int arr[], int n) {int i;//建立一个大顶堆for (i = n / 2 - 1; i >= 0; i--)heap(arr, i, n );//排序for (i = n - 1; i > 0; i--) {//注意边界条件,笔者这个大傻子在这卡了两天swap(arr[i], arr[0]);//交换最后一个娃子,使其最大值从无序组脱离,来到有序组heap(arr, 0, i);    }
}

其中heap函数数用来维护堆的,也就是让被取数和存数操作破坏性质的数据(即父节点不一定是最大值了)重新变成大顶堆。(一次只能处理一个元素)

2.

void heap(int arr[], int x, int n)
{arr[0] = arr[x];//把目标元素暂存在哨兵中for (int i = 2 * x;i <= n;i*=2) {//按层向下遍历if (i < n && arr[i] < arr[i + 1])i++;if (arr[0] >= arr[i])//如果父亲节点大于两个孩子的最大值,调整结束break;else {//如果不行,直接覆盖掉,有哨兵不用一个一个交换了arr[x] = arr[i];x = i;}}arr[x] = arr[0];//把哨兵的值还给目标位
}void Heapsort(int arr[], int n) {int i;for (i = n / 2;i > 0;i--)heap(arr, i, n);for (i = n;i > 1;i--) {swap(arr[i], arr[1]);heap(arr, 1, i - 1);}
}

这个方法用了哨兵,简化了对于N的处理。而且用循环替代了递归复杂度也小很多。调整堆中元素的思路有点像排序树的增加和删除操作。

二、二分插入排序

所谓二分插入排序就是利用二分查找来优化插入排序,即每次依照插入排序中无序组的待插入元素的值,找到他在有序组应该在的位置,然后插入。

void Misort(int arr[], int x) {int i, j, high, mid, low;for (i = 2;i <= x-1 ;i++) {arr[0] = arr[i];low = 1;high = i - 1;//查找位置while (low <= high) {mid = (high + low) / 2;if (arr[mid] < arr[0])low = mid + 1;elsehigh = mid - 1;}for (j = i - 1;j >= high + 1;--j)arr[j + 1] = arr[j];arr[high+1] = arr[0];}
}

堆排序、二分插入排序(C++代码)相关推荐

  1. 我的Java开发学习之旅------Java经典排序算法之二分插入排序

    一.折半插入排序(二分插入排序) 将直接插入排序中寻找A[i]的插入位置的方法改为采用折半比较,即可得到折半插入排序算法.在处理A[i]时,A[0]--A[i-1]已经按关键码值排好序.所谓折半比较, ...

  2. C语言排序方法-----二分插入排序

    由于在直接插入排序过程中,待插入数据左边的序列总是有序的,针对有序序列,就可以用二分法去插入数据了,也就是二分入排序法.适用于数据量比较大的情况. 二分插入排序的算法思想是: (1)计算 0 ~ i- ...

  3. python插入排序_python简单的实现插入排序和二分插入排序

    零:环境 Python 3.6.5 JetBrains PyCharm 2018.1.4 x64 一:正常的插入排序 插入排序如字面意思,是将数据一个一个的插入到列表里以形成有序数列 插入排序的前提是 ...

  4. 深入理解插入排序(why二分插入排序中left就是待插入位置)

    >> 插入排序 本编重点在最后: 为什么二分插入left总是指向待插入的位置? 插入排序的思路: 给定一个数组,将数组划分为,已排序和未排序两部分,默认第一个元素已排序,然后一次遍历未排序 ...

  5. 二分插入排序法-Python版

    简介: 传统的插入法思想为: 1.从头开始,构建有序数列: 2.再将之后需要排序的数据从头至尾(或从尾至头)进行比较,插入到其相应的位置. 而二分插入排序法第一步与传统插入法相同,第二步而是采用二分查 ...

  6. 简单排序算法时间空间复杂度分析及应用(4)-二分插入排序

    简单排序算法时间空间复杂度分析及应用(4)-二分插入排序 背景: 顾名思义,这个二分插入排序是直接插入排序的进化版,主要变化的地方就是在内循环部分,即外循环的循环节点在确定区域的位置查询方式由原来的直 ...

  7. java二分排序法原理_Java常见排序算法详解—— 二分插入排序

    转载请注明出处: 二分插入排序Binary Insert Sort 概念: 二分(折半)插入排序是一种在直接插入排序算法上进行小改动的排序算法.其与直接排序算法最大的区别在于查找插入位置时使用的是二分 ...

  8. 常见排序算法之二分插入排序算法

    1.算法思路 是在插入第i个元素时(i前面的元素必定是有序的),对前面的0-i-1元素进行折半,先跟他们中间的那个元素比, 如果小,则对前半再进行折半,否则对后半进行折半, 直到left>rig ...

  9. 二分查找 java代码实现

    文章目录 二分查找java代码 单元测试 二分查找java代码 package csdn.dreamzuora.query;/*** Title: 二分查找* Description:* 时间复杂度: ...

最新文章

  1. Python 多进程/Event 重复使用唤醒
  2. ExecutorService- Future - Java多线程编程
  3. iframe高度自适应(IE6+、FF、Opera、Chrome等测试通过)
  4. Java toBinaryString()函数探究及Math.abs(-2147483648)=-2147483648原理探究
  5. UTF-8, ASCII, Unicode的介绍与区分
  6. python 数组打包_Python:打包多字节数组
  7. 在多线程数据平面开发套件(DPDK)应用程序中优化内存使用
  8. App云端打包失败常见问题汇总
  9. Linux虚拟机添加新硬盘的全程图解
  10. 在计算机中打开word2010三种方法,Word2019中打开文档的三种方式
  11. An Empirical Analysis of Anonymity in Zcash
  12. python的数组下标_python数组下标
  13. spring的BeanFactory和ApplicationContext
  14. 《Android开源库》 Google 最新Hover Menu(悬浮菜单)
  15. python实现千牛客服自动回复语_千牛自动回复设置话术
  16. 雅睿生物在创业板IPO终止:安信证券为保荐人,曾计划募资7.5亿元
  17. 老男孩老师的博客地址
  18. 【信息学奥赛一本通】1134:合法C标识符查
  19. linux常用命令,自己总结
  20. elastica php yii,Yii 1.1.*集成elasticsearch php 客户端Elastica

热门文章

  1. web前端学习笔记——Day6(js)
  2. hutool写excel
  3. PowerMock 简介
  4. c语言库函数大全pdf 百度云,c 语言库函数大全
  5. 2019年“最惨”的老板:公司倒了,员工跑了,自己也被抓了
  6. python导入模块中函数或者变量的方法
  7. 如何解决li标签中不能添加文字在图片正下方
  8. 如何将word中所有数字和字母设置成红色 加粗 倾斜
  9. 【网络】IPV4数据报头部格式
  10. android vlayout 刷新,关于使用vlayout控件时候,加载更多数据刷新的问题