归并排序的主要思想是将两个有序的部分归并成一个有序的整体,这一关键的实现方法如下
每个部分都有详细注释
public class MergeSort {
public static void merge(Comparable[] a,int lo,int mid,int hi) {
Comparable[] b = new Comparable[hi-lo+1]; //建立一个同样大小的新数组,存放排好序的结果
int i = lo; //第一个有序序列的索引
int j = mid+1; //第二个有序序列的索引
for(int k =0;k<b.length;k++){ //循环新数组,获取每一个值
if (i>mid) { //当第一个序列索引到结尾后,直接去第二个序列的值
b[k] = a[j];
j++;
}
else if (j>hi) { //当第二个序列索引到结尾后,直接去第一个序列的值
b[k]= a[i];
i++;
}
else if (less(a[i],a[j])) { //选择两个序列中当前索引较小的那一个
b[k] = a[i];
i++;
}
else {
b[k] = a[j];
j++;
}
}
int ss = lo;
for (int j2 = 0; j2 < b.length; j2++) { //将排好序的数组赋值给a
a[ss++] = b[j2];
}
}
private static boolean less(Comparable c1, Comparable c2) { //判断c1是否小于c2
return c1.compareTo(c2)<0;
}
}
测试一下该方法的可行性,数据1,2,3,6,7,8,2,3,5,5,6,9前六位为一个序列,后六位为一序列,将这两个有序列排好序
public static void main(String[] args) {
Integer[] a = {1,2,3,6,7,8,2,3,5,5,6,9};
merge(a, 0, 5, 11);
for (Integer i : a) {
System.out.println(i);
}
}
结果如下
1 2 2 3 3 5 5 6 6 7 8 9 |
当然,在给定两个有序的序列的条件下才能实现排序,这个显然还不是一个有效的排序算法,因此,归并算法上调用递归的思想,实现对任意的数组排序,在其中的if(lo>=hi)的条件,一开始我没有添加该部分,程序会出现Exception in thread "main" java.lang.StackOverflowError栈溢出的错误,该条件能及时的停止递归
public class MergeSort {
public static void mergeSort(Comparable[] a) {
mergeSort(a,0,a.length-1);
}
private static void mergeSort(Comparable[] a, int lo, int hi) {
if (lo>=hi) {
return;
}
int mid = (lo+hi)/2;
mergeSort(a, lo, mid);
mergeSort(a, mid+1, hi);
merge(a, lo, mid, hi);
}
public static void main(String[] args) {
Integer[] a = {1,2,3,2,1,6,7,8,5,3,2,5,3,6,3};
mergeSort(a);
for (Integer integer : a) {
System.out.println(integer);
}
}
}
输出结果如下
1 1 2 2 2 3 3 3 3 5 5 6 6 7 8 |