排序算法之归并排序

不念不忘少年蓝@ 2023-07-13 04:09 100阅读 0赞

归并排序介绍

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

将两个的有序数列合并成一个有序数列,称之为”归并”

归并排序基本思想

(1)分(分解):一开始对当前数组一分为二,并求出当前数组的中间索引 int middleIndex = (startIndex + endIndex) / 2;

(2)求解:递归地对两个子数组array[startIndex …middleIndex ]、array[middleIndex +1…endIndex]进行归并排序,递归的结束条件是子数组的长度为1

(3)治(合并):将已排序的两个子数组array[startIndex …middleIndex ]、array[middleIndex +1…endIndex]合并为一个有序的子数组array[startIndex …endIndex]

归并排序图解过程

format_png

将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终有序序列[1,2,3,4,5,6,7,8],步骤 如下

format_png 1

代码实现

  1. package com.zzb.sort;
  2. import java.util.Arrays;
  3. /**
  4. * @Auther: Administrator
  5. * @Date: 2020/3/10 12:41
  6. * @Description: 归并排序
  7. */
  8. public class MergeSort {
  9. public static void main(String[] args) {
  10. int[] array = {8, 4, 5, 7, 1, 3, 6, 2};
  11. // 每次合并时,存放有序序列的临时数组
  12. int[] tempArray = new int[array.length];
  13. mergeSort(array, 0, array.length - 1, tempArray);
  14. System.out.println(Arrays.toString(array));
  15. /*[1, 2, 3, 4, 5, 6, 7, 8]*/
  16. }
  17. /**
  18. * 归并排序算法(题外话:整个算法类似于二叉树的节点的后序遍历操作)
  19. * @param array 将要被拆分的数组
  20. * @param startIndex 将要被拆分数组的头部索引
  21. * @param endIndex 将要被拆分数组的尾部索引
  22. * @param tempArray 每次合并时,存放有序序列的临时数组
  23. */
  24. private static void mergeSort(int[] array, int startIndex, int endIndex, int[] tempArray) {
  25. // 对数组进行递归拆分,直到每一个子数组中只有一个元素时递归拆分结束
  26. if(startIndex < endIndex) {
  27. // 被拆分数组的中间索引
  28. int middleIndex = (startIndex + endIndex) / 2;
  29. // 左递归拆分数组(题外话:整个算法类似于二叉树的节点的后序遍历操作)
  30. mergeSort(array, startIndex, middleIndex, tempArray);
  31. // 右递归拆分数组(题外话:整个算法类似于二叉树的节点的后序遍历操作)
  32. mergeSort(array, middleIndex + 1, endIndex, tempArray);
  33. // 合并排序
  34. merge(array, startIndex, middleIndex, endIndex, tempArray);
  35. }
  36. }
  37. /**
  38. * 归并排序算法 合并两个有序序列为一个有序序列(题外话:整个算法类似于二叉树的节点的后序遍历操作)
  39. * @param array 被拆分后的待排序数组
  40. * @param startIndex 被拆分后的待排序数组的头部索引
  41. * @param middleIndex 被拆分后的待排序数组的中间索引
  42. * @param endIndex 被拆分后的待排序数组的尾部索引
  43. * @param tempArray 每次合并时,存放有序序列的临时数组
  44. */
  45. private static void merge(int[] array, int startIndex, int middleIndex, int endIndex, int[] tempArray) {
  46. // startIndex 至 endIndex(包括startIndex与endIndex)索引之间的元素被拆分为两个子数组后,左边子数组的开始索引
  47. // 初始值为startIndex
  48. int left = startIndex;
  49. // startIndex 至 endIndex(包括startIndex与endIndex)索引之间的元素被拆分为两个子数组后,左边子数组的结束索引
  50. int right = middleIndex;
  51. // startIndex 至 endIndex(包括startIndex与endIndex)索引之间的元素被拆分为两个子数组后,右边子数组的开始索引
  52. // 初始值为middleIndex+1
  53. int l = middleIndex+1;
  54. // startIndex 至 endIndex(包括startIndex与endIndex)索引之间的元素被拆分为两个子数组后,右边子数组的结束索引
  55. int r = endIndex;
  56. // 临时数组tempArray初始值
  57. int tempArrayIndex = 0;
  58. // 左右子数组中的元素比较大小进行排序
  59. while(left <= right && l <= r) {
  60. if(array[left] < array[l]) {
  61. tempArray[tempArrayIndex] = array[left];
  62. left ++;
  63. tempArrayIndex ++;
  64. }
  65. if(array[left] > array[l]) {
  66. tempArray[tempArrayIndex] = array[l];
  67. l ++;
  68. tempArrayIndex ++;
  69. }
  70. }
  71. // 存在左边子数组或者右边子数组有剩余元素的可能
  72. while(left <= right) {
  73. tempArray[tempArrayIndex] = array[left];
  74. left ++;
  75. tempArrayIndex ++;
  76. }
  77. while(l <= r) {
  78. tempArray[tempArrayIndex] = array[l];
  79. l ++;
  80. tempArrayIndex ++;
  81. }
  82. // 把临时数组tempArray已排序好的元素复制到原数组array中的相应索引位置
  83. tempArrayIndex = 0;
  84. while(startIndex <= endIndex) {
  85. array[startIndex] = tempArray[tempArrayIndex];
  86. startIndex ++;
  87. tempArrayIndex ++;
  88. }
  89. }
  90. }

发表评论

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

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

相关阅读

    相关 排序算法归并排序

    归并排序是一种基于分治思想的排序算法,它的基本思路是将原始序列划分为若干个子序列,对每个子序列进行排序,然后将排好序的子序列合并为一个大序列,最终得到排序结果。具体来说,归并排

    相关 排序算法归并排序

    归并排序 基本思想:归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使用每个子序列有

    相关 排序算法归并排序

    归并排序> 之前曾经实现过堆排序,它用到了完全二叉树,但是堆的设计本身就是比较复杂的,而今天要实现的归并排序同样的也用到了完全二叉树的思想,这种思想比堆排序较为简单.

    相关 排序算法归并排序

    归并排序是利用递归与分治思想将数据序列划分成越来越小的半子序列,在对其进行排序,最后利用递归将排好序的半子序列合并成越来越大的有序序列。 归并排序中,归 即是递归的意思,即递