1 自顶向下的归并排序
/*** 归并排序的递归方法*/public class MergeSort implements Sort {private int[] aux;@Overridepublic void sort(int[] arr) {aux = new int[arr.length];mergeSort(arr, 0, arr.length - 1);}// 定义排序的区间是 [l, r] 闭区间private void mergeSort(int[] arr, int l, int r) {if (l >= r)return;int mid = l + (r - l) / 2;mergeSort(arr, l, mid);mergeSort(arr, mid + 1, r);merge(arr, l, mid, r);}// 归并方法private void merge(int[] arr, int l, int mid, int r) {System.arraycopy(arr, l, aux, l, r - l + 1);int i = l;int j = mid + 1;for (int k = l; k <= r; k++) {if (i > mid)arr[k] = aux[j++];else if (j > r)arr[k] = aux[i++];else if (aux[i] <= aux[j])arr[k] = aux[i++];elsearr[k] = aux[j++];}}}
2 自底向上的归并排序
- sz:每次要归并的数组的长度,从1开始,之后每次的长度变为原来的2倍,即sz += sz;另外sz可以等于数组的长度;
- i:代表第一个归并数组的起始位置,从0开始,每次递增2个size长度,即i += sz + sz;
- 每次归并的数组为 [i, i + sz - 1] 和 [i + sz, i +2sz - 1];
- 边界问题:
- 确保第二个数组的起始位置不越界,即i + sz < arr.length;
确保第二个数组的结束位置不越界,即每次的取值为:组长度与i + sz + sz - 1的较小的值。
public class MergeSortBU implements Sort {@Overridepublic void sort(int[] arr) {for (int sz = 1; sz <= arr.length; sz += sz) {for (int i = 0; i + sz < arr.length; i += sz + sz) {merge(arr, i, i + sz - 1, Math.min(arr.length - 1, i + sz + sz - 1));}}}}
3 扩展
- 自底向上的归并排序并没有使用数组的索引,所以可以将此方法用到链表上;
完成对链表的自底向上的归并排序。
[ ] 148. 排序链表
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
