自己的理解
归并排序感觉比快速排序简单一点...反正我觉得好理解一点..
1.把1个要排序的数组拆分成2个要排序的小数组(可以直接取中间元素,分成2个一样长度的小数组).
2.对每个小数组继续拆分,拆分到只有一个元素.
3.把2个小数组重合归并成一个排好序的大数组,然后这个大数组再和其他大数组归并成一个更大的数组....循环下去最后归并成一开始完整的数组.
实现
1 package algorithm; 2 3 import java.util.Arrays; 4 5 /** 6 * 合并排序 7 * 8 * @author jyzjyz12@163.com 9 * @since 2017年2月27日 上午10:25:48 10 */ 11 public class MergeSortTest1 { 12 public static void main(String[] args) { 13 int[] arr1 = { 4, 7, 5, 6, 1, 3, 8 }; 14 int[] arr2 = { 7, 6, 5, 4, 3, 2, 1 }; 15 int[] arr3 = { 5, 9, 3, 7, 8, 6, 1, 2, 4 }; 16 int[] arr4 = { 13, 2, 5, 4, 88, 76, 68, 87, 55, 88, 88, 77, 67, 99, 100, 5, 53, 52, 51, 66 }; 17 sort(arr1); 18 sort(arr2); 19 sort(arr3); 20 sort(arr4); 21 System.out.println(Arrays.toString(arr1)); 22 System.out.println(Arrays.toString(arr2)); 23 System.out.println(Arrays.toString(arr3)); 24 System.out.println(Arrays.toString(arr4)); 25 } 26 27 public static void sort(int[] arr) { 28 sort(arr, 0, arr.length - 1); 29 } 30 31 /** 32 * 排序,可以只排序low到high的位置的数字 33 * 34 * @param arr 35 * 待排序数组 36 * @param low 37 * 要排序数组的开始下标位置 38 * @param high 39 * 要排序数组的终止下标位置 40 */ 41 private static void sort(int[] arr, int low, int high) { 42 // 先把数组拆分再合并 43 if (low == high) { // 当数组只有1个元素的时候不需要再拆分 44 return; 45 } 46 int mid = (low + high) / 2;// 准备把数组拆分成2个小部分 47 sort(arr, low, mid);// 再把前半部分再拆分成1半和1半 48 sort(arr, mid + 1, high);// 再把后半部分再拆分成1半和1半 49 merge(arr, low, high, mid);// 把各自排好序的两部分合并起来.合并时候也需要重新排下序,因为虽然2个小部分是排好序的,但是不能保证一个小部分的每个元素都比另外一部分大或者小,可能也有交叉. 50 } 51 52 /** 53 * 把各自排好序的2部分合并起来(需要重新排下序) 54 * 55 * @param arr 56 * 带排序数组 57 * @param low 58 * 两部分最小的下标 59 * @param high 60 * 两部分最大的下标 61 * @param mid 62 * 左半部分最后一个数字的下标 63 */ 64 private static void merge(int[] arr, int low, int high, int mid) { 65 int[] temp = new int[high - low + 1]; // 2部分总共有多少个数字,排好序存放在这个数组里 66 int leftPointer = low;// 左半部分最小的下标 67 int rightPointer = mid + 1;// 右半部分最小的下标 68 int currPointer = 0;// 遍历temp用 69 while (leftPointer <= mid && rightPointer <= high) { // 左半部分循环结束或者右半部分循环结束 70 if (arr[leftPointer] <= arr[rightPointer]) { // 左边数组的数字<=右边数组的数字 71 temp[currPointer++] = arr[leftPointer++];// 把左边的数字放到temp中,然后currPointer指向temp中下一个空着的位置,左边数字的指针向后移动 72 } else {// 左边数组的数字>右边数组的数字 73 temp[currPointer++] = arr[rightPointer++];// 把右边的数字放到temp中,然后currPointer指向temp中下一个空着的位置,右边数字的指针向后移动 74 } 75 } 76 // while结束的时候肯定至少有一个数组所有元素已经全部放到temp里了 77 if (leftPointer > mid) { // 如果左边的数组已经全部拷贝到temp里了 78 for (int i = rightPointer; i <= high;) { 79 temp[currPointer++] = arr[i++];// 把右边剩下的元素拷贝到temp里 80 } 81 } 82 83 if (rightPointer > high) { // 如果右边的数组已经全部拷贝到temp里了 84 for (int i = leftPointer; i <= mid;) { 85 temp[currPointer++] = arr[i++];// 把左边剩下的元素拷贝到temp里 86 } 87 } 88 89 // 把temp覆盖回arr的low-high的位置 90 int tempPointer = low; 91 for (int i = 0; i < temp.length; i++) { 92 arr[tempPointer++] = temp[i]; 93 } 94 } 95 }