归并排序
归并排序介绍
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer) 策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
归并排序思想示意图
1-基本思想:
2-合并相邻有序子序列:
再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤
代码实现
1. public class mergesort { 2. public static void main(String[] args) { 3. int[] arr = {8, 4, 4, -4, 1, 3, 6, 2}; 4. int[] temp = new int[arr.length]; 5. System.out.println("原数组为:" + Arrays.toString(arr)); 6. mergeSort(arr, 0, arr.length - 1, temp); 7. System.out.println("排序后数组为:" + Arrays.toString(arr)); 8. } 9. 10. /** 11. * 分+合方法 12. * @param arr 需要排序的数组 13. * @param left 左边有序序列的初始索引 14. * @param right 右边索引 15. * @param temp 做中转的数组 16. */ 17. private static void mergeSort(int[] arr, int left, int right, int[] temp) { 18. if (left < right) { 19. int mid = (left + right) / 2;//中间索引 20. mergeSort(arr, left, mid, temp);//向左递归进行分解 21. mergeSort(arr, mid + 1, right, temp);//向右递归进行分解 22. 23. merge(arr, left, mid, right, temp);//合并 24. } 25. } 26. 27. //合并的方法 28. private static void merge(int[] arr, int left, int mid, int right, int[] temp) { 29. int i = left;//标记第一个子数组的最左端 .初始化 i, 左边有序序列的初始索引 30. int j = mid + 1;//标记第二个子数组的最左端. 初始化 j, 右边有序序列的初始索引 31. int t = 0;// 指向 temp 数组的当前索引 32. 33. //(一) 34. //先把左右两边(有序)的数据按照规则填充到 temp 数组 35. //直到左右两边的有序序列,有一边处理完毕为止 36. while (i <= mid && j <= right) { 37. //如果左边的有序序列的当前元素,小于等于右边有序序列的当前元素 38. //即将左边的当前元素,填充到 temp 数组 39. //然后 t++, i++ 40. if (arr[i] <= arr[j]) { 41. temp[t] = arr[i]; 42. i++; 43. t++; 44. } else { 45. temp[t] = arr[j];//反之,将右边有序序列的当前元素,填充到 temp 数组 46. j++; 47. t++; 48. } 49. } 50. 51. //(二) 52. //把有剩余数据的一边的数据依次全部填充到 temp 53. while (i <= mid) { 54. temp[t] = arr[i]; 55. i++; 56. t++; 57. } 58. while (j <= right) { 59. temp[t] = arr[j]; 60. j++; 61. t++; 62. } 63. 64. //(三)!!!!重点理解 65. //将 temp 数组的元素拷贝到 arr 66. //注意,并不是每次都拷贝所有 67. int templeft = left; 68. //例如: 69. //第一次合并 tempLeft = 0 , right = 1 70. //第二次:tempLeft = 2,right = 3 //第三次: tL=0 ri=3..... 71. //最后一次 tempLeft = 0 right = 7 72. t = 0; 73. while (templeft <= right) { 74. arr[templeft] = temp[t]; 75. t++; 76. templeft++; 77. } 78. } 79. }