基本思想:将若干有序序列逐步归并,最终归并成一个有序序列。
二路归并排序
基本思想:将序列分为若干有序序列(开始为单个记录),两个相邻有序的序列合并成一个有序的序列,重复进行,直到整个序列有序。
一次归并过程:两个有序序列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一样,都是已排序好的序列。
}