1. 工作原理(定义)

归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法,指的是将两个已经排序的序列合并成一个序列的操作。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:

  • 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法);
  • 自下而上的迭代;

2. 算法步骤

1. 从下往上的归并排序【迭代】:

  1. 通过分治法将长度为n的序列划分为n个长度为1的子序列。

  2. 进行两两归并比较,得到 n/2 个长度为 2 的有序子序列

  3. 重复第 2 步,直到所有子序列归并成一个长度为 n 的有序序列。

2. 从上往下的归并排序【递归】:

  1. 分解 -- 将当前区间一分为二,即求分裂点 mid = (low + high)/2;

  2. 求解 -- 递归地对两个子区间a[low...mid] 和 a[mid+1...high]进行归并排序。递归的终结条件是子区间长度为1。

  3. 合并 -- 将已排序的两个子区间a[low...mid]和 a[mid+1...high]归并为一个有序的区间a[low...high]。

3. 归并步骤:

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;

  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置;

  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;

  4. 重复步骤 3 直到某一指针达到序列尾;

  5. 将另一序列剩下的所有元素直接复制到合并序列尾。

  

3. 动画演示

  

  

4. 性能分析

1. 时间复杂度

  归并排序的效率是比较高的,设数列长为N,将数列分开成小数列一共要 logN 步,每步都是一个合并有序数列的过程,时间复杂度可以记为O(N),故一共为O(N*logN),故时间复杂度为O(nlogn)。

2. 空间复杂度

  归并排序过程中,需要一个辅助空间来暂存两有序子文件归并的结果,因此空间复杂度为O(n)。

3. 算法稳定性

  归并是稳定的算法,在分解和并归过程中元素相对顺序未发生改变。

4. 初始顺序状态

  1. 比较次数:
  2. 移动次数:
  3. 复杂度:
  4. 排序趟数:

5. 归位

  不能归位

6. 优点

  1. 排序:速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列
  2. 求逆序对数:在归并的过程中计算每个小区间的逆序对数,进而计算出大区间的逆序对数(也可以用树状数组来求解)

7. 具体代码

public class MergeSort {// 归并排序(从上往下,递归)public static void mergeSortUp2Down(int [] arr, int start, int end){if(arr!=null && start<end){//当子序列中只有一个元素时结束递归int mid=(start+end)/2;//划分子序列mergeSortUp2Down(arr, start, mid);//对左侧子序列进行递归排序mergeSortUp2Down(arr, mid+1, end);//对右侧子序列进行递归排序merge(arr, start, mid, end);//合并
        }}//归并排序(从下往上,迭代)public static void mergeSortDown2Up(int [] arr){if(arr!=null){int len = arr.length;//gap表示有序数组的长度(1,2,4,8……)for(int gap = 1; gap < len; gap*=2){int i;// 将"每2个相邻的子数组" 进行合并排序。for(i = 0; i+2*gap-1 < len; i+=(2*gap)){merge(arr, i, i+gap-1, i+2*gap-1);}// 若 i+gap-1 < len-1,则剩余一个子数组没有配对。// 将该子数组合并到已排序的数组中。if (i+gap-1 < len-1){merge(arr, i, i+gap-1, len-1);}}}}//两路归并算法,两个排好序的子序列合并为一个子序列public static void merge(int []arr, int left, int mid, int right){int []tmp=new int[arr.length];//辅助数组int p1=left,p2=mid+1,k=left;//p1、p2是检测指针,k是存放指针while(p1<=mid && p2<=right){if(arr[p1]<=arr[p2])tmp[k++]=arr[p1++];elsetmp[k++]=arr[p2++];}while(p1<=mid) tmp[k++]=arr[p1++];//如果第一个序列未检测完,直接将后面所有元素加到合并的序列中while(p2<=right) tmp[k++]=arr[p2++];//同上//复制回原素组for (int i = left; i <=right; i++) arr[i]=tmp[i];}public static void main(String[] args){int[] arr = { 49, 38, 65, 97, 76, 13, 27, 50 };//mergeSortUp2Down(arr, 0, a.length-1);
        mergeSortDown2Up(arr);System.out.println("排好序的数组:");for (int e : arr)System.out.print(e+" ");}
}

8. 参考网址

  1. 数据结构基础学习笔记目录
  2. 排序算法系列之并归排序
  3. 图解排序算法(四)之归并排序
  4. https://visualgo.net/en/sorting
  5. https://www.runoob.com/w3cnote/merge-sort.html
  6. https://github.com/hustcc/JS-Sorting-Algorithm
  7. 归并排序
  8. Java实现归并排序-有图有真相

转载于:https://www.cnblogs.com/haimishasha/p/10856561.html

数据结构与算法系列——排序(10)_归并排序相关推荐

  1. 数据结构与算法系列——排序(3)_折半插入排序

    1. 工作原理(定义) 二分插入排序(Binary Insertion Sort,折半插入排序 OR 拆半插入排序),采用折半查找方法. 二分查找插入排序的原理:是直接插入排序的一个变种:区别是:在有 ...

  2. 数据结构排序算法实验报告_[数据结构与算法系列]排序算法(二)

    我的上一篇文章向大家介绍了排序算法中的冒泡排序.插入排序和选择排序.它们都是平均时间复杂度为 O(n^2) 的排序算法,同时还为大家讲解了什么是原地排序和什么是排序的稳定性.下图是这三种算法的比较,不 ...

  3. 数据结构和算法之排序一:归并排序

    我们不得不承认一个事实,java学习过程中如果我们掌握了各种编程手段和工具,确实可以做一些开发,这就是一些培训机构敢告诉你几个月就能掌握一门语言的原因.但是随着时间的发展,我们总会感觉,这一类人如果不 ...

  4. 希尔排序的详细过程_算法系列: 10大常见排序算法(4)希尔排序

    本课程是从少年编程网转载的课程,目标是向中学生详细介绍计算机比赛涉及的编程语言,数据结构和算法.编程学习最好使用计算机,请登陆 www.3dian14.org (免费注册,免费学习). 一句 希尔排序 ...

  5. 导师计划--数据结构和算法系列(上)

    导师计划已经开始一个月了,自己的讲解的课程选择了数据结构和算法.这个系列的讲解分为上下两章,javascript语言辅助.本篇文章为上章,涉及的内容是基本的数据结构.在日本,晚上没事安排@-@,时间还 ...

  6. 导师计划 -- 数据结构和算法系列(上)

    导师计划已经开始一个月了,自己的讲解的课程选择了数据结构和算法.这个系列的讲解分为上下两章,javascript语言辅助.本篇文章为上章,涉及的内容是基本的数据结构.在日本,晚上没事安排@-@,时间还 ...

  7. 数据结构与算法(三) 排序算法(代码示例)

    数据结构与算法三 排序算法 1. 选择排序 2. 插入排序 3. 冒泡排序 4. 归并排序 5. 快速排序 6. 希尔排序 7. 堆排序 总结 1. 选择排序 选择排序的基本原理: 对于未排序的一组记 ...

  8. 数据结构与算法之排序算法

    数据结构与算法之排序算法 排序算法的介绍 ​ 排序也称排序算法(Sort Algorithm),排序是将一组数据,依指定的顺序进行排序的过程. 排序的分类 1)内部排序:指将需要处理的数据都加载到内部 ...

  9. 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)

    常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...

最新文章

  1. 深度学习必懂的 13 种概率分布(附链接)
  2. 霍夫变换直线检测理解
  3. php cache缓存 购物车,Yii2使用Redis缓存购物车等数据
  4. matlab多项式相乘的法则_卷积计算与多项式乘法
  5. 机柜服务器选择学问大!
  6. qt vs插件 qt-vsaddin下载
  7. 深入理解java虚拟机 (一) 第二版
  8. 二次元带音乐404源码
  9. 李永乐复习全书线性代数 第三章 向量
  10. 鸟哥的Linux私房菜基础学习篇 第2章的重点探索
  11. linux格式化u盘为ntfs格式,Linux上格式化U盘为NTFS格式
  12. storm源码分析研究(五)
  13. Python爬虫入门心得分享
  14. WSL 解决code .报‘code‘ not fount无法打开Vscode问题
  15. 网易云音乐的API接口及爬虫代码
  16. C语言复习03(小甲鱼版本)
  17. 【转】FAL_CLIENT和FAL_SERVER参数详解
  18. mysql数据库查询练习二-【比经理工资还高员工姓名】【查找重复的邮箱】
  19. 将IP地址更新到3323域名
  20. 加法的横式竖式教案c语言,20以内竖式加减法教案

热门文章

  1. Oracle回收站解决误删除表
  2. Git安装后安装目录改变
  3. php隔行符,PHP PHP_EOL 换行符
  4. 开源 RPC 框架有哪些
  5. pack unpack 用法 转载
  6. Lucene就是这么简单
  7. Web安全之点击劫持
  8. linux C(hello world)三个数最大和三个数最新
  9. [转载] 推荐的C++书籍以及阅读顺序
  10. mysql5.5启动报错:The server quit without updating PID file ([FAILED]localhost.localdomain.pid)....