代码:

 1 public static void mergeSort(int[] arr) {
2 if (arr == null || arr.length < 2) {
3 return;
4 }
5 mergeSort(arr, 0, arr.length - 1);
6 }
7
8 public static void mergeSort(int[] arr, int l, int r) {
9 if (l == r) {
10 return;
11 }
12 int mid = l + ((r - l) >> 1);
13 mergeSort(arr, l, mid); //左侧有序
14 mergeSort(arr, mid + 1, r); //右侧有序
15 merge(arr, l, mid, r); //merge
16 }
17
18 public static void merge(int[] arr, int l, int m, int r) {
19 int[] help = new int[r - l + 1];
20 int i = 0;
21 int p1 = l;
22 int p2 = m + 1;
23 while (p1 <= m && p2 <= r) {
24 help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++]; //谁小拷贝谁(p1和p2都不越界)
25 }
26 while (p1 <= m) {
27 help[i++] = arr[p1++];
28 }
29 while (p2 <= r) {
30 help[i++] = arr[p2++];
31 }
32 for (i = 0; i < help.length; i++) {
33 arr[l + i] = help[i];
34 }
35 }

如果看代码的流程,归并排序的是把一组数据,一分为二,之后对左边的数据继续一分为二,分到实在不能再分(也就是l == r的时候)

最后再排序!这其实是分而治之的思想,假设有5个数【2,4,9,6,3】我们直接排序不好排,但是如果我们分一下呢?

变成【2,4】和【9,6,3】如果对左边再分一次呢?

【2】、【4】这时候2 和 4 都是单独的一个数,我们显然知道单独的一个数是最好排序的,2 和4 本身就是有序的,因为它们只有自己!

对于左边,当分到不能再分的时候return;,递归调用的“递”的过程就完成了,接下来就是归了。

在归的过程中,会多次进入右侧的递归函数,但是由于 l == r 所以实质上右侧的调用是无效的,只需要调用merge函数完成左侧单个数据

的依次排序!

当左侧完成的时候,会进入最初始的那个 l 和 r 的值,接下来再次进入右侧的递归函数,完成同样的一个过程,最后左侧数据和右侧数据

都是各自有序的,当程序跳出(mergeSort(arr, mid + 1, r); //右侧有序)这一行代码的时候,会执行最外层函数的最后一次merge,这时候

对所有数据完成最后一次排序参数应该是最初的参数,也就是 l = 0 ; mid = 2 ; r = 4 ! merge(0,2.4) 这时候所有数据就都是有序的了!

代码的执行顺序?

当进入一条递归语句的时候,会多次循环整个过程,只有当满足结束条件的时候,才会return!

但此时要注意,这时候return只是退出了这一条语句而已,对于最外层的函数来说,只是这一条

语句执行完毕了。还是需要继续往下执行的,也就是会进入下一条递归语句,对于归并排序来说

先进入左边递归,左边有序,之后进入右边递归,右边有序!最后进入最外层的函数执行最后一

条merge语句,把整个数组完成排序!

下面是我画的一个草图:

该图片来自:https://www.cnblogs.com/l199616j/p/10604351.html

【Java】归并排序的更多相关文章

  1. java归并排序,单线程vs多线程

    一.什么是归并排序 归并排序又称合并排序,它是成功应用分治技术的一个完美例子.对于一个需要排序的数组A[0..n-1],归并排序把它一分为二:A[0..n/2-1]和A[n/2..n-1],并对每个子 ...

  2. java归并排序

    代码如下: public class MergeSort { public static void mergeSort(DataWrap [] data) { sort(data , 0 , data ...

  3. java归并排序详解

    归并排序 /**   * 归并排序   * 简介:将两个(或两个以上)有序表合并成一个新的有序表 即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列   * 时间 ...

  4. Java归并排序的递归与非递归实现

    该命题已有无数解释,备份修改后的代码 平均时间复杂度: O(NLogN)  以2为底 最好情况时间复杂度: O(NLogN) 最差情况时间复杂度: O(NLogN) 所需要额外空间: 递归:O(N + ...

  5. 23. Merge K Sorted Lists (Java, 归并排序的思路)

    题目:Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity ...

  6. 8 Java 归并排序(MergerSort)

    图片素材与文字描述来自:尚硅谷-韩顺平数据结构与算法. 1.基本思想 归并排序是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divi ...

  7. Java 归并排序

    package cookie; public class MergeSort { void mergeSort(int[] a, int[] temp, int left, int right) { ...

  8. Hark的数据结构与算法练习之归并排序

    算法说明: 归并排序的思路就是分而治之,将数组中的数字递归折半进行排序. 递归到最底层就只剩下有两个数字进行比较,再从底层往下进行排序合并.最终得出结果. 同样,语言描述可能对于不知道这个算法的人来说 ...

  9. Java数据结构和算法 - 递归

    三角数字 Q: 什么是三角数字? A: 据说一群在毕达哥拉斯领导下工作的古希腊的数学家,发现了在数学序列1,3,6,10,15,21,……中有一种奇特的联系.这个数列中的第N项是由第N-1项加N得到的 ...

  10. 20172328 2018-2019《Java软件结构与数据结构》第五周学习总结

    20172328 2018-2019<Java软件结构与数据结构>第五周学习总结 概述 Generalization 本周学习了第九章:排序与查找,主要包括线性查找和二分查找算法和几种排序 ...

随机推荐

  1. spring boot+sqlite+mybatis实现增删改查例子

    主要是更换了下sqlite的数据源而已,其他代码不变. 我都贴一下吧,这个算是比较通用的基础增删改查代码. 1.创建test.db 可以使用Idea自带的Database插件配置,也可以命令行创建,具 ...

  2. Go语言并发编程(4):sync包介绍和使用(下)-Once,Pool,Cond

    sync包下:Once,Pool,Cond 一.sync.Once 执行一次 Once 简介 sync.Once 是 Go 提供的让函数只执行一次的一种实现. 如果 once.Do(f) 被调用多次, ...

  3. python中操作csv

    示例 import csv with open('t.csv', mode='r', encoding='utf-8') as f: reader_obj = csv.reader(f) # 通过re ...

  4. 【LeetCode动态规划#09】完全背包问题实战,其二(零钱兑换和完全平方数--求物品放入个数)

    零钱兑换 力扣题目链接(opens new window) 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能 ...

  5. 为产品的一堆Visual Studio解决方案引入Directory.Build.props

    为什么需要Directory.Build.props? 一个产品有了多个甚至几十个解决方案之后,每个解决方案里面的项目可能会引用一个dll包的不同版本,因此需要集中管理dll包的版本号. .NET的D ...

  6. 【Azure 应用服务】Azure App Service多实例中,出现某一个实例CPU居高不下的情况,如何重启单个实例呢?

    问题描述 在使用App Service服务中,当多实例中,其中一个实例出现高CPU,高Memory的情况,为了尽可能少的影响正在运行的应用,需要单独重启某一个实例的情况下,如何手动操作呢? 问题解答 ...

  7. 【Azure API 管理】API Management service (APIM) 如何实现禁止外网访问

    问题描述 API Management service 设置禁止外网访问,请求通过外网(Internet)将无法解析到APIM的网关地址,只能通过APIM所集成的内网(Virtual Network) ...

  8. STM32FATFS文件系统移植

    STM32FATFS文件系统移植 1. FATFS简介 FATFS文件系统是一个用于在微控制器上运行的开源文件系统,支持FAT/FATFS.NTFS.exFAT等主流文件系统,且一直保持更新.在此以F ...

  9. Java 递归方法的使用 + 例子

    1 /* 2 * 递归方法的使用 3 * 1.递归方法:一个方法体内调用它自身 4 * 2.方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制 5 * 递归一定要想已知方向 ...

  10. 11、mysql的SQL执行顺序

    编写顺序 SELECT DISTINCT <select list> FROM <left_table> <join_type> JOIN <right_ta ...