归并排序

归并排序是将一个序列划分为同样大小的两个子序列,然后对两个子序列分别进行排序,最后进行合并操作,将两个子序列合成有序的序列.在合成的过程中,一般的实现都需要开辟一块与原序列大小相同的空间,以进行合并操作,所以我们需要最大O(n)的辅助空间用于存储合并序列。下面是归并排序的过程。

原地归并排序

原地递归排序的步骤与递归排序一样,都是划分成子序列然后合并子序列,但在实现合并子序列的时候使用了手摇算法实现了序列的合并,可以做到O(1)的辅助空间,但是理论上合并长度为n和m的子序列最坏的复杂度为2*n*m,所以原地归并排序实际意义并不大,但是也可以给我们进行参考。

手摇算法

其实手摇算法的思想很简单,但我口才不好,只能用实际演示给你们看:
假如要将序列1 2 3 4 5的4 5提到1 2 3前面
-> 1 2 3 4 5 原数组
-> 3 2 1 5 4 O(n)的时间将1 2 3翻转,4 5翻转
-> 4 5 1 2 3 O(n)的时间再将数组翻转一次
这时候我们可以看到4 5已经在1 2 3的前面了。我们可以清楚地看到每个数都被交换了2次,所以手摇算法的时间复杂度是2*(n+m)

原地归并算法的实现

我们已经知道了什么是手摇算法,这时候我们可以来演示一下怎么合并两个排好序的序列:
1. 1 3 5 2 4 6 这时的l=0,m=3,r=6,[l,m)是一个序列[m,r)是一个序列,子序列都在list数组里面
2. 1 3 5 2 4 6 比较list[l]和list[m]的大小
3. 当list[l] <= list[m]的时候l++,重复2步骤,当list[l] > list[m]或者l >= m时往下走
4. 1 3 5 2 4 6 这时的l = 1,m = 3,r = 6 再次比较list[l]和list[m]的大小
5. 当list[l] > list[m]的时候m++,重复4步骤并且使用move记录重复次数,当list[l] <= list[m]或者m >= r时往下走
6. 1 3 5 2 4 6 这时的l = 1,m = 4,r = 6
7. 这时候我们可以保证[m-move,m)的序列比list[l]小,所以我么可以使用手摇算法交换[l,m-move)和[m-move,m)的顺序,然后l+=move,因为这时候3的位置在l+move处。
8. 1 2 3 5 4 6 这时候l = 2,m = 4,r = 6,我们重复2步骤继续交换,直到排好顺序。

c++代码实现归并排序和原地归并排序

template<class T>
class MergeSort
{
public:enum Type {On,O1//归并排序的辅助空间复杂度};void Sort(T *list, int size, Type t = On) {if (t == On)MergeOn(list, 0, size);else MergeO1(list, 0, size);}
private:void MergeSortOn(T *list, int l,int m, int r) {//[l,m),[m,r)T *a = new T [r - l + 1];int index = 0,mid = m,s=l;while (l < mid && m < r) {if (list[l] < list[m])a[index++] = list[l++];else a[index++] = list[m++];}while (l < mid)a[index++] = list[l++];while (m < r)a[index++] = list[m++];for (int i = s, j = 0; i < r; i++, j++)list[i] = a[j];delete []a;}void MergeOn(T *list,int l,int r){//[l,r)if (l + 1 >= r)return;int m = (l + r) / 2;MergeOn(list, l, m);MergeOn(list, m, r);MergeSortOn(list, l, m, r);}void swap(T& a, T& b) {T c = a;a = b;b = c;}void reverse(T *list, int l, int r) {//[l,r)r--;while (l < r)swap(list[l++], list[r--]);}void hand(T *list, int l, int m, int r) {//手摇算法reverse(list, l, m);reverse(list, m, r);reverse(list, l, r);}void MergeSortO1(T *list, int l, int m, int r) {while (l < m && m < r) {while (l < m && list[l] <= list[m]) l++;int move = 0;while (m < r && list[l] > list[m])move++, m++;hand(list, l, m - move, m);l += move;}}void MergeO1(T *list, int l,int r) {//[l,r)if (l + 1 >= r)return;int m = (l + r) / 2;MergeO1(list, l, m);MergeO1(list, m, r);MergeSortO1(list, l, m, r);}
};

归并排序(O(n)辅助空间)与原地递归排序(O(1)辅助空间)相关推荐

  1. 快速排序和归并排序中一趟的理解(递归和非递归)

    引:2019年408中数据结构一道考察快速排序的选择题 答案:D 定位:这道题在考察快速排序中一趟的概念.注意,基本的冒泡,插入,选择排序的一趟概念很容易理解, 接下来我们要讨论的是递归排序算法中(本 ...

  2. 一步一步写算法(之非递归排序)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 在上面一篇博客当中,我们发现普通查找和排序查找的性能差别很大.作为一个100万的数据,如果使用 ...

  3. 名图空间实测_【图】名图:空间大油耗低,关键还直降3.8万!_汽车之家

    随着生活压力的增加和生活节奏的加快,相比买房的高昂成本,人们越来越倾向于先买一辆爱车来好好犒劳自己.这样上下班不仅有个便捷的代步工具,同时如果想自驾游或者平时和朋友出去玩,有辆自己的车开起来也更加方便 ...

  4. mysql 表空间收缩_mysql表碎片清理和表空间收缩

    mysql表碎片清理和表空间收缩(即清理碎片后report_site_day.ibd文件磁盘空间减小,该方案基于独立表空间存储方式) OPTIMIZETABLE [tablename],当然这种方式只 ...

  5. 算法笔记-递归算法、递归排序、递归的时间复杂度、master公式(也叫主方法)

    1. 递归排序题 通过递归算法来获取一个数组中的最大值 2. 算法思路 采用递归的思路来进行解题,那么肯定是需要自己调用自己的,这也就是递归,于是考虑怎么自己调用自己呢?我们可以采用二分法来制造递归的 ...

  6. ftp 文件完整性校验_FTP空间是什么?如何获取免费FTP空间吗?

    FTP是File Transfer Protocol的简称,又被称为文件传输协议,是一种将数据上传和下载到Internet的方式.FTP是一套公认的且简单的协议,是传输单个文件以及多个文件的一个最有效 ...

  7. 辅助改方办理方法 计算机联锁,辅助所

    工业企业专用线在区间正线上接轨时,在接轨地点应设置辅助所.为贯彻责任制及保证机车车辆的运行安全,区间道岔须由辅助所管理. 中文名 辅助所 定    义 工业企业专用线在区间正线区    间 道岔须由辅 ...

  8. RBF神经网络——直接看公式,本质上就是非线性变换后的线性变化(RBF神经网络的思想是将低维空间非线性不可分问题转换成高维空间线性可分问题)...

    Deeplearning Algorithms tutorial 谷歌的人工智能位于全球前列,在图像识别.语音识别.无人驾驶等技术上都已经落地.而百度实质意义上扛起了国内的人工智能的大旗,覆盖无人驾驶 ...

  9. Oracle数据库查看表空间sql语句、查看Oracle数据库表空间剩余 、修改表空间、库备份

    一  Oracle数据库查看表空间sql语句 1.oracle查看表空间当前用户 SQL>  select  username,default_tablespace  from user_use ...

最新文章

  1. FAQ about AJAX-part II
  2. 如何玩转跨库Join?跨数据库实例查询应用实践
  3. 计算机视觉库OpenCV中shape和resize函数的区别
  4. ffmpeg rtp时间戳
  5. Kudu安装前的建议说明(博主推荐)
  6. shell 获取 mysql 行数_一个Shell小脚本精准统计Mysql每张表的行数实现
  7. 何谓成功的软件架构设计
  8. POJ 2115 C Looooops
  9. 硬件:关于ARM的22个常用概念!
  10. 海南大学计算机原理,海南大学微机原理课件 第一章 计算机基础知识
  11. 用U盘作为启动盘做系统步骤
  12. Django 框架02: 模型与站点
  13. opend和open的区别_open与open up的区别
  14. iis swagger 部署_asp.net-core – 虚拟目录中的IIS站点Swagger UI端点
  15. THREEJS - mousedown/mouseup等鼠标相关事件失效
  16. Delphi7--循环结构语句
  17. Visio_Premium_project_vol版
  18. 计算机怎么语音通话,微信电脑版怎么语音聊天?微信电脑版语音聊天教程
  19. 使用Tensorflow2.0实现roi-Align和FPN
  20. android 酷我音乐接口,酷我音乐 各种付费歌曲,音质包括ape、flac无损音乐api接口...

热门文章

  1. u盘在ubuntu系统下突然变成只读文件
  2. flask连接数据库——flask-SQLALchemy
  3. JavaScript返回1970年1月1日至今的毫秒数的方法getTime()
  4. 收藏这些vue项目性能优化方式,总有一天能用上
  5. 网络安全保险的新兴发展与监管研究
  6. ScrollView示例
  7. 孩子没有身份证如何坐火车
  8. java高级工程师必会专业技能
  9. linux中数字转换成字符,各种数字类型转换成字符串型
  10. fstransform开源工具支持Linux下无损转换文件系统