基本思想:将若干有序序列逐步归并,最终归并成一个有序序列。
二路归并排序
基本思想:将序列分为若干有序序列(开始为单个记录),两个相邻有序的序列合并成一个有序的序列,重复进行,直到整个序列有序。
一次归并过程:两个有序序列a、b,目标数组c。每次往目标数组c中放一个记录,a、b序列谁小就放谁。直到一个数组全部放入目标数组,对另一个进行收尾工作。
归并的递归实现:
- 将数组拆分成单个记录的子序列(递的过程,入栈)
- 将相邻两个有序序列合并成有序序列。(归的过程,出栈)
二路归并数组
/** * 将两个数组合并,每次往目标数组中放一个元素,谁元素小就放谁<br> * 直到一个数组全部放入目标数组,对另一个进行收尾工作。<br> * * @param arr1 * @param arr2 * @return */ public static int[] mergeArray(int[] arr1, int[] arr2) { int size1 = arr1.length; int size2 = arr2.length; int[] temp = new int[size1 + size2];//目标数组 int i = 0, j = 0, k = 0; while (i < size1 && j < size2) {// 直到一个数组全部放入目标数组 if (arr1[i] < arr2[j]) temp[k++] = arr1[i++]; else temp[k++] = arr2[j++]; } MyPrinter2.printArr(temp); // 收尾工作 while (i < size1) temp[k++] = arr1[i++]; while (j < size2) temp[k++] = arr2[j++]; MyPrinter2.printArr(temp); return temp; }
二路归并排序的递归实现-java
/** * 将两个相邻的有序区间source[first~mid],source[mid+1~last]合并到temp数组中<br> * * @return */ public static void merge(int[] source, int[] temp, int first, int mid, int last) { int i = first, j = mid + 1; int k = 0; while (i <= mid && j <= last) {// 直到一个数组全部放入目标数组 if (source[i] < source[j]) temp[k++] = source[i++]; else temp[k++] = source[j++]; } // 收尾工作 while (i <= mid) temp[k++] = source[i++]; while (j <= last) temp[k++] = source[j++]; // 将归并结果放入原数组中。 for (i = 0; i < k; i++) source[first + i] = temp[i]; } public static void mergeSort(int[] source, int[] temp, int first, int last) { if (first < last) { int mid = (first + last) / 2; mergeSort(source, temp, first, mid); //归并排序前半个子序列 mergeSort(source, temp, mid + 1, last); //归并排序后半个子序列 merge(source, temp, first, mid, last); } else if (first == last) { //待排序列只有一个,递归结束 temp[first] = source[first]; } } public static void msort(int[] arr) { int size = arr.length; int[] temp = new int[size]; mergeSort(arr, temp, 0, size - 1); //此时temp与arr一样,都是已排序好的序列。 }