- 归并排序体现了分治的思想
- 实现方法:
- 将数据分为两组,再比较两组的第一个元素,较小的放入我们最终要输出的数组中,较大的放回原数组,再进行下一次比较。
- 这时候我们会发现比较出来的元素不符合我们的顺序的需求
- 这是因为归并排序的分组要求两个组是有序的
- 那么怎么办呢,我们将原数组再度分组,一直到一组里只有一个元素为止,此时就可以确保组内有序
归并排序
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/f250744fd64b423247e3355212b7e0fe.png#pic_center)
自底向上的归并排序:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/6acccfc4af17f5a79315469356cd4123.png#pic_center)
自顶向下的归并排序
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/63e38b8b90d31acd6ac61ed9a7f8d936.png#pic_center)
public class MergeBU {
private static Comparable[] aux;
public static void merge(Comparable[] a, int lo, int mid, int hi) {
int i = lo, j = mid + 1;
for (int k = lo; k <= hi; k++) {
aux[k] = a[k];
}
for (int k = lo; k <= hi; k++) {
if (i > mid) {
a[k] = aux[j++];
} else if (j > hi) {
a[k] = aux[i++];
} else if (less(aux[j], aux[i])) {
a[k] = aux[j++];
} else {
a[k] = aux[i++];
}
}
}
public static void sort(Comparable[] a) {
int N = a.length;
aux = new Comparable[N];
for (int sz = 1; sz < N; sz = sz + sz) {
for (int lo = 0; lo < N - sz; lo += sz + sz) {
merge(a, lo, lo + sz - 1, Math.min(lo + sz + sz - 1, N - 1));
}
}
}
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
private static void exch(Comparable[] a, int i, int j) {
Comparable t = a[i];
a[i] = a[j];
a[j] = t;
}
}
public class MergeSortTopToDown {
private static Comparable[] aux;
public static void merge(Comparable[] a, int lo, int mid, int hi) {
int i = lo, j = mid + 1;
for (int k = lo; k <= hi; k++) {
aux[k] = a[k];
}
for (int k = lo; k <= hi; k++) {
if (i > mid) {
a[k] = aux[j++];
} else if (j > hi) {
a[k] = aux[i++];
} else if (less(aux[j], aux[i])) {
a[k] = aux[j++];
} else {
a[k] = aux[i++];
}
}
}
public static void sort(Comparable[] a) {
aux = new Comparable[a.length];
sort(a, 0, a.length - 1);
}
private static void sort(Comparable[] a, int lo, int hi) {
if (hi <= lo) {
return;
}
int mid = lo + (hi - lo) / 2;
sort(a, lo, mid);
sort(a, mid + 1, hi);
merge(a, lo, mid, hi);
}
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
private static void exch(Comparable[] a, int i, int j) {
Comparable t = a[i];
a[i] = a[j];
a[j] = t;
}
}
public class ImproveMergeSort {
private static int CUTOFF = 15;
public static void merge(Comparable[] src, Comparable[] dest, int lo, int mid, int hi) {
int i = lo, j = mid + 1;
for (int k = lo; k <= hi; k++) {
if (i > mid) {
dest[k] = src[j++];
} else if (j > hi) {
dest[k] = src[i++];
} else if (less(src[j], src[i])) {
dest[k] = src[j++];
} else {
dest[k] = src[i++];
}
}
}
public static void sort(Comparable[] a) {
Comparable[] aux = a.clone();
sort(aux, a, 0, a.length - 1);
}
private static void sort(Comparable[] src, Comparable[] dest, int lo, int hi) {
if (hi - lo < CUTOFF) {
insertionSort(dest, lo, hi);
return;
}
int mid = lo + (hi - lo) / 2;
sort(dest, src, lo, mid);
sort(dest, src, mid + 1, hi);
if (less(src[mid + 1], src[mid])) {
merge(src, dest, lo, mid, hi);
}
}
public static void insertionSort(Comparable[] a, int lo, int hi) {
for (int i = lo; i <= hi; i++) {
for (int j = i; j > lo && less(a[j], a[j - 1]); j--) {
exch(a, j, j - 1);
}
}
}
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
private static void exch(Comparable[] a, int i, int j) {
Comparable t = a[i];
a[i] = a[j];
a[j] = t;
}