【排序算法】- 归并排序

系统管理员 2022-12-20 06:12 194阅读 0赞

文章目录

  • 1 归并排序介绍:
  • 2 归并排序思想示意图1-基本思想:
  • 3 归并排序思想示意图2-合并相邻有序子序列:
  • 4 归并排序的应用实例:
  • 5 一张排序算法的比较图

1 归并排序介绍:

归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案”修补”在一起,即分而治之)。

2 归并排序思想示意图1-基本思想:

在这里插入图片描述

3 归并排序思想示意图2-合并相邻有序子序列:

再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤
在这里插入图片描述

4 归并排序的应用实例:

给你一个数组,val arr = Array(8,4,5,7,1,3,6,2),请使用归并排序完成排序。
代码演示:

  1. package com.sukang.sort;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Arrays;
  4. import java.util.Date;
  5. /**
  6. * @description:
  7. * 归并排序
  8. * @author: sukang
  9. * @date: 2020-11-11 12:49
  10. */
  11. public class MergetSort {
  12. public static void main(String[] args) {
  13. //测试快排的执行速度
  14. //创建要给80000个的随机的数组
  15. int[] arr = new int[80000];
  16. for (int i = 0; i < 80000; i++) {
  17. arr[i] = (int)(Math.random()*8000000);//生成一个[0,8000000)数
  18. }
  19. //没排序之前数组遍历
  20. System.out.println("排序前的数组" + Arrays.toString(arr));
  21. Date date1 = new Date();
  22. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  23. String date1Str = simpleDateFormat.format(date1);
  24. System.out.println("排序前的时间是=" + date1Str);
  25. int temp[] = new int[arr.length];//归并排序需要一个额外空间
  26. mergeSort(arr,0,arr.length-1, temp);
  27. Date date2 = new Date();
  28. String date2Str = simpleDateFormat.format(date2);
  29. System.out.println("排序后的时间是="+date2Str);
  30. //排序之后数组遍历
  31. System.out.println("排序后的数组" + Arrays.toString(arr));
  32. }
  33. //分 + 合方法
  34. public static void mergeSort(int[] arr, int left, int right, int[] temp){
  35. if(left < right){
  36. int mid = (left + right)/2; //中间索引
  37. //向左递归进行分解
  38. mergeSort(arr,left,mid,temp);
  39. //向右递归进行分解
  40. mergeSort(arr,mid+1,right,temp);
  41. //合并
  42. merge(arr,left,mid,right,temp);
  43. }
  44. }
  45. /**
  46. * @description:
  47. * 合并的方法
  48. * @param arr 排序的原始数组
  49. * @param left 左边有序序列的初始索引
  50. * @param mid 中间索引
  51. * @param right 右边索引
  52. * @param temp 做中转的数组
  53. * @return: void
  54. * @author: sukang
  55. * @date: 2020/11/11 12:55
  56. */
  57. private static void merge(int[] arr, int left, int mid, int right, int[] temp) {
  58. int i = left;//初始化i,左边有序序列的初始索引
  59. int j = mid + 1; //初始化j,右边有序序列的初始索引
  60. int t = 0; //指向temp数组的当前索引
  61. //(一)
  62. //先把左右两边(有序)的数据按照规则填充到temp数组
  63. //直到左右两边的有序序列,有一边处理完毕为止
  64. while(i <= mid && j <= right) {//继续
  65. //如果左边的有序序列的当前元素,小于等于右边有序序列的当前元素
  66. //即将左边的当前元素,填充到temp数组
  67. //然后t++,i++
  68. if(arr[i] <= arr[j]){
  69. temp[t] = arr[i];
  70. t += 1;
  71. i += 1;
  72. } else {//反之,将右边有序序列的当前元素,填充到temp数组
  73. temp[t] = arr[j];
  74. t += 1;
  75. j += 1;
  76. }
  77. }
  78. //(二)
  79. //把有剩余数据的一边的数据依次全部填充到temp
  80. while(i <= mid) {//左边的有序序列还有剩余的元素,就全部填充到temp
  81. temp[t] = arr[i];
  82. t += 1;
  83. i += 1;
  84. }
  85. while(j <= right) {//右边的有序序列还有剩余的元素,就全部填充到temp
  86. temp[t] = arr[j];
  87. t += 1;
  88. j += 1;
  89. }
  90. //(三)
  91. //将temp数组的元素拷贝到arr
  92. //注意,并不是每次都拷贝所有
  93. t = 0;
  94. int tempLeft = left;//
  95. //第一次合并tempLeft=0,right=1 //tempLeft=2right=3 //tL=0ri=3
  96. //最后一次 tempLeft=0 right=7
  97. while(tempLeft <= right){
  98. arr[tempLeft] = temp[t];
  99. t += 1;
  100. tempLeft += 1;
  101. }
  102. }
  103. }

运行结果
在这里插入图片描述

5 一张排序算法的比较图

在这里插入图片描述
相关术语解释
1)稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面;
2)不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面;
3)内排序:所有排序操作都在内存中完成;
4)外排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行;
5)时间复杂度:一个算法执行所耗费的时间。
6)空间复杂度:运行完一个程序所需内存的大小。
7)n:数据规模
8)k:“桶”的个数
9)In-place:不占用额外内存
10)Out-place:占用额外内存

发表评论

表情:
评论列表 (有 0 条评论,194人围观)

还没有评论,来说两句吧...

相关阅读

    相关 排序算法——归并排序

    引言 归并排序可以使用递归或迭代的方式来实现,时间复杂度是都是 O(N \ logN)。 归并排序的核心是将待排序数组分组,可以整体二分,也可以设置步长迭代切分。归并排

    相关 排序算法-归并排序

    归并排序也是一个比较快速的排序算法,其思想是运用分治的思想,先对要排序的数进行分,每次从中间分成两部分,然后知道分成最小,然后在把他们合起来,边合起来边排序,最后有序,每次分的

    相关 排序算法——归并排序

    前言 将待排序序列R\[0...n-1\]看成是n个长度为1的有序序列,将相邻的有序表成对归并,得到n/2个长度为2的有序表;将这些有序序列再次归并,得到n/4个长度为4

    相关 排序算法归并排序

    一、前言     归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用 分治法(Divide and Conquer) 的一个非常典型的应用。 --------