归并排序
归并排序基于归并操作——将两个有序的数组组合成一个更大的有序数组,进而发展为递归排序算法——归并排序,即将数组分成量半,分别排序,然后归并。
归并排序的时间复杂度为O(NlogN),空间复杂度为O(N)。
merge(a, lo, mid, hi) 将子数组 a[lo..mid] 和 a[mid+1..hi] 归并为一个有序数组,将结果放在 a[lo..hi]。将所有元素复制到一个辅助数组中,然后归并回原数组。
/**
* 归并排序
* 将两个有序数组归并成一个更大的有序数组
* 时间复杂度NlogN,空间复杂度N
*/
public class Merge extends Sort {
@Override
public void sort(Comparable[] a) {
if (a == null || a.length < 2) {
return;
}
aux = new Comparable[a.length];
sort(a, 0, a.length - 1);
}
private static Comparable[] aux;
private void sort(Comparable[] a, int low, int high) {
if (low >= high) return;
int mid = (low + high) / 2;
sort(a, low, mid);
sort(a, mid + 1, high);
merge(a, low, mid, high);
}
private void merge(Comparable[] a, int low, int mid, int high) {
int i = low, j = mid + 1;
for (int k = low; k <= high; k++) {
aux[k] = a[k];
}
for (int k = low; k <= high; k++) {
if (i > mid) {
a[k] = aux[j++];
} else if (j > high) {
a[k] = aux[i++];
} else if (less(aux[i], aux[j])) {
a[k] = aux[i++];
} else {
a[k] = aux[j++];
}
}
}
}
改进
- 对小子数组使用插入排序
- 测试数组是否有序
- 避免复制到辅助数组