归并排序,其实就是递归+合并。

归并排序将数组取中间分为两部分,两个子数组分别各自再从中间分为两个子数组,一直分下去直到不能再分。分完之后,再按照子数组大小合并为为一个有序数组,然后层层向上合并,直到合并为一个有序的数组。

文字描述不理解的话,使用一副图来解释下:

其实归并排序的思想很简单,图中也描述的很清楚。

归并排序的时间复杂度为O(nlogn),跟冒泡、选择、插入这三种排序O(n^2)的时间复杂度不同,要有效率很多。

我们把代码呈上:

 /*** 归并排序* @param arr* @param n*/public static void mergeSort(int[] arr,int n){mergeSort(arr,0,n-1);}/*** 递归程序* @param arr* @param p* @param r**/public static void mergeSort(int[] arr,int p,int r){if(p>=r){return;}int q = (p+r)/2;mergeSort(arr,p,q);mergeSort(arr,q+1,r);//合并merge(arr,p,q,r);}/*** 合并* @param arr* @param p* @param q* @param r*/public static void merge(int[] arr,int p,int q,int r){int i =p,j=q+1,k=0;int[] temp = new int[r-p+1];while(i<=q && j<=r){//当两个区间中元素相等的时候,取arr(p,q)得加入temp,可以做到归并算法的稳定性if(arr[i] <= arr[j]){temp[k++]=arr[i++];}else{temp[k++]=arr[j++];}}//判断arr(p,q)和arr(q+1,r)哪个有剩余的数据int start=i,end=q;if(j<=r){start=j;end=r;}//将剩余数据拷贝到临时数组temp中while(start <= end){temp[k++]=arr[start++];}//将temp中的数据拷贝回arr(p,r)数组中for (int l = 0; l <= r-p; l++) {arr[p+l]=temp[l];}}

归并排序使用的是分治思想,分治思想简单说就是分而治之,将一个大问题分解为小问题,将小问题解答后合并为大问题的答案。乍一看跟递归思想很像,确实如此,分治思想一般就是使用递归来实现的。

需要说明的是,递归是代码实现,分治思想是解决问题的方法论,属于理论层面的

其实mergeSort这个函数就是使用递归层层分解问题的。可以看到将数组的大区间[p,r]从中间分开,分成两个小区间[p,q]和[q+1,r]

/*** 递归程序* @param arr* @param p* @param r**/public static void mergeSort(int[] arr,int p,int r){if(p>=r){return;}int q = (p+r)/2;mergeSort(arr,p,q);mergeSort(arr,q+1,r);//合并merge(arr,p,q,r);}

层层分解,直到满足递归终止条件:p>=r,就说明分到最后1个不能再分了。既然无法再分,那接着就进行合并了。看起来merge函数写的很复杂,其实如果理解了思想就非常容易理解了,千万不能被吓到。一切反动派都是纸老虎!

归并排序是原地排序算法吗?

不是原地算法,归并排序在合并函数中使用到了temp临时数组用来存放[p,r]区间元素,这个临时存储空间在merge函数结束后就释放了,所以归并排序的空间复杂度保持在O(n).

归并排序是稳定排序算法吗?

归并排序到底是不是稳定排序算法,关键在合并的时候,合并的时候可以选择对两个区间中相等的元素,取[p,q]的元素先放入temp数组中,保证了等值元素合并前后的存放顺序。所以归并排序是稳定排序算法。

归并排序算法的时间复杂度是多少?

假如n个元素使用归并排序的时间复杂度为T(n),那么由于归并排序使用的是分治思想,T(n)=2*T(n/2)+n,其中n就是两个子区间合并的时间复杂度,这个从合并函数可以看出来。可以推导出以下公式:

T(1) = C;   n=1 时,只需要常量级的执行时间,所以表示为 C。
                         T(n) = 2*T(n/2) + n; n>1

经过进一步推导,可以得到T(n)=2^k * T(n/2^k) + k * n,我们假设T(1)=T(n/2^k),也就是说当n/2^k个元素的进行归并排序,达到递归终止条件时,n/2^k=1,得到:k=logn

于是:

 T(n)=Cn+nlog2n

归并排序的时间复杂度就是O(nlogn),跟数组的有序度其实并没有什么关系,是非常稳定的时间复杂度。

排序算法-归并排序的时间复杂度分析相关推荐

  1. 常用排序算法稳定性、时间复杂度分析

    1. 选择排序.快速排序.希尔排序.堆排序不是稳定的排序算法,      冒泡排序.插入排序.归并排序和基数排序是稳定的排序算法. 2.研究排序算法的稳定性有何意义? 首先,排序算法的稳定性大家应该都 ...

  2. 排序算法-快速排序的时间复杂度分析

    快速排序的思想是在数组[p,r]中选择一个分区点q,将数组一分为2,同时将小于分区点的数值的放到分区点左侧[p,q-1],大于分区点的数值的放到分区点右侧[q+1,r],重复这个过程. 快速排序也是用 ...

  3. 排序算法-插入排序的时间复杂度分析

    插入排序的原理是,将数组分为已排序区间和未排序区间两部分,从未排序区间中依次取元素跟已排序区间的元素一一对比,找到适合插入的位置. 拿数组[4,5,6,1,3,2]来举例,如图所示是排序的图解过程.这 ...

  4. 排序算法-冒泡排序的时间复杂度分析

    冒泡排序算法是一种基于比较的排序算法,每次冒泡过程,都会有一个数据确定位置.经过n次冒泡后,就有n个数据确定了位置. 如图所示,对数组[4,5,6,3,2,1]进行冒泡排序.  起初,按照最原始的想法 ...

  5. python排序算法——归并排序(附代码)

    python排序算法 --归并排序 文章目录 python排序算法 --归并排序 一.前言 二.算法描述 三.代码实现 总结 一.前言 相关知识来自<python算法设计与分析>.初级排序 ...

  6. 十大经典排序算法-归并排序算法详解

    十大经典排序算法 十大经典排序算法-冒泡排序算法详解 十大经典排序算法-选择排序算法详解 十大经典排序算法-插入排序算法详解 十大经典排序算法-希尔排序算法详解 十大经典排序算法-快速排序算法详解 十 ...

  7. 排序算法中平均时间复杂度_操作系统中的作业排序(算法,时间复杂度和示例)...

    排序算法中平均时间复杂度 作业排序 (Job sequencing) Job sequencing is the set of jobs, associated with the job i wher ...

  8. 经典排序算法 - 归并排序Merge sort

    经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每一个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到全部合并完,形成有序的数组 举例 无序数组[6 ...

  9. 查找和排序算法的学生成绩分析实验

    基于查找和排序算法的学生成绩分析实验 一.实验内容 二.实验原理 三.实验代码记录 四.实验结果 一.实验内容 编写程序将自己学号后面的8位同学的学号.姓名以及数学.英语和数据结构的成绩信息保存到学生 ...

最新文章

  1. cmd 修改文件属性
  2. 4一20ma电流有源与无源区别_4-20 mA电流环的工作原理是怎么样的
  3. javascript onsubmit返回false仍然能提交_JavaScript对象-Get和Put
  4. 《系统集成项目管理》第十四章 项目采购管理
  5. android源码分析之JNI调用与回调
  6. json 反序列化 父子类型_Json的序列化和反序列化
  7. 今天开始复习toefl,mark一下
  8. centos7安装es mysql_Centos7 安装MySQL详细步骤
  9. 使用C#控制远程计算机的服务[转]
  10. activemq spring 集成与测试
  11. 解决NSTimer循环引用
  12. 卸载精灵(bue directx) r4.0 完美版 是什么
  13. 【视频通话卡顿】【语音通话卡顿】PC端QQ、微信每天接通语音电话或视频通话总会出现首卡半分钟左右的童鞋请进
  14. 烘培赛道的2021:资本重押下,老字号向左,新秀向右?
  15. LeetCode 1134.阿姆斯特朗数 每日一题
  16. 虹科Automation softPLC | 虹科KPA MoDK运行环境与搭建步骤(2)——MoDK运行环境搭建
  17. 简单易懂应如何快速掌握超长激光测距仪相关性能指标TFNLR20KI激光测距仪带你走进其简单的世界
  18. DontDestroyOnLoad带来的麻烦
  19. 推荐几款免费视频格式转换软件,比格式工厂更好用
  20. MeterSphere | 超好用的开源测试平台

热门文章

  1. 2020/04/09 03-模拟登陆和页面等待
  2. 西安邮电大学计算机学院转专业面试,2020年西安邮电大学转专业,大一新生转专业和入学考试...
  3. 懒加载原理以及实现思路
  4. Promise学习笔记一
  5. 第09周:吴恩达 Andrew Ng 机器学习
  6. (c/c++)REPEAT程序,prog文件,真正的做法
  7. php 重定向 无效,php – 重定向头功能不起作用
  8. cv2 Grabcut图像分割
  9. 微信小程序ios滑动问题(滑动卡顿,下拉拖动自定义导航栏)
  10. 【HDU 2512】第二类斯特林数