import java.util.Arrays;
/**
* 题:实现归并排序
* 描述:将含有n个元素的待排序表看成n个单位元素个数的子表,两两归并排序,得到n/2(取整)个长度为2或者1的有序表
* 再两两归并,知道合并成一个长度为n的有序表
* */
public class MergeSort {
public static void merge (int[] arr, int low, int mid, int high) {
int[] temp = new int[arr.length]; // 建立一个与arr同长的空数组
int i = low;
int j = mid + 1;
int k = 0;
for (i = low, j = mid + 1, k = i;
i <= mid && j <= high ; k++) { // k从i开始
if (arr[i] <= arr[j]) { // 比较子表左右两边的元素
temp[k] = arr[i++]; // 将较小的值赋值给temp
}else {
temp[k] = arr[j++];
}
System.out.println(Arrays.toString(temp));
}
while (i <= mid) { // 左边子表没有检测完,将剩余元素复制到temp
temp[k++] = arr[i++];
System.out.print("tempM : " + k + " ");
System.out.println(Arrays.toString(temp));
}
while (j <= high) { // 右边子表没有检测完,将剩余元素复制到temp
temp[k++] = arr[j++];
System.out.print("tempH : " + k + " ");
System.out.println(Arrays.toString(temp));
}
for(int m = low; m <= high; m++) { // 每次要将数组中相应位置的的变化传递给原数组
arr[low] = temp[m]; // arr要从子序列的low开始,而temp要从0
}
System.out.println(Arrays.toString(arr));
}
/**
* 分解数组
* 对于递归调用的还不是很熟
* @param arr 原数组
* @param low (子)序列最左边的序号
* @param high (子)序列最右边的序号
*/
public static void mergeSort (int[] arr, int low, int high) {
if (low < high) {
int mid = (low + high)/2;
mergeSort(arr,low, mid);
mergeSort(arr,mid + 1, high);
merge(arr, low, mid, high);
}
}
public static void main(String[] args) {
int x[] = {6, 5, 4, 3, 2, 1, 11, 8, 9, 13, 0};
mergeSort(x, 0, x.length - 1);
System.out.println(Arrays.toString(x));
}
}
- 总结:
- 1、对于归并排序理解的还不是很清楚;
- 2、具体实现中考虑的不全,比如只考虑到将子序列中较小的部分复制,忽略了没有检测的部分;
- 3、对于递归调用的顺序没太理解,mergeSort()方法中的执行顺序不熟悉;
- 4、不太会用调试;