归并排序
-层级log(N)
-归并过程时间复杂度O(N)
-需要额外的O(N)空间
以空间换时间
-总时间复杂度O(Nlog(N))
具体实现
public class MergeSort {
// 归并排序
public static <T extends Comparable<? super T>> void MergeSort(T[] arr, int n) {
sonOfMergeSort(arr, 0, n - 1);
}
// 递归使用归并排序,对arr[l...r]的范围进行排序
private static <T extends Comparable<? super T>> void sonOfMergeSort(T[] arr, int l, int r) {
// if (l >= r) {
// return;
// }
// 当n小到一定程度时,插入排序比归并排序快
if (r - l <= 15) {
// 当分块中元素为15+1时,换成插入排序
SelectionSort.insertionSort(arr,r,l);
return;
}
int mid = (l + r) / 2;
sonOfMergeSort(arr, l, mid);
sonOfMergeSort(arr, mid + 1, r);
// 若满足if则序列为有序的,对近乎有序的数组会起到优化作用
if (arr[mid].compareTo(arr[mid + 1]) > 0) {
merge(arr, l, mid, r);
}
}
// 将arr[l...mid]和arr[mid+l..r]两部分进行归并
public static <T extends Comparable<? super T>> void merge(T[] arr, int l, int mid, int r) {
T[] aux = arr.clone();
for (int i = l; i <= r; i++)
aux[i - l] = arr[i];
int i = l, j = mid + 1;
for (int k = l; k <= r; k++) {
if (i > mid) {
arr[k] = aux[j - l];
j++;
} else if (j > r) {
arr[k] = aux[i - l];
i++;
} else if (aux[i - l].compareTo(aux[j - l]) < 0) {
arr[k] = aux[i - l];
i++;
} else {
arr[k] = aux[j - l];
j++;
}
}
}
// 自底向上的归并排序
// 未使用数组索引,可以使用链表访问
public static <T extends Comparable<? super T>> void mergeSortBU(T[] arr, int n) {
for (int i = 1; i < n; i += i) {
for (int j = 0; j + i < n; j += i + i) {
// 对arr[j..j+i-1]和对arr[j..j+i+i-1]进行归并,并对可能得越界问题进行处理
MergeSort.merge(arr, j, j + i - 1, Math.min(j + i + i - 1, n - 1));
}
}
}
}