自顶向下的归并排序(使用递归)
/**
* 自顶向下的归并排序
* @author XY
*
*/
@SuppressWarnings("rawtypes")
public class MergeSort {
private static Comparable[] temp;
public static void sort(Comparable[] v){//归并排序
int N=v.length;
temp=new Comparable[N];//数组的创建不能放在递归的方法中,那样会造成多次创建数组。
int lo=0;
int hi=N-1;
sort(v, lo, hi);
}
public static void sort(Comparable[] v,int lo,int hi){
if(lo>=hi) return;
int mid=lo+(hi-lo)/2;
sort(v, lo, mid);
sort(v, mid+1, hi);
merge(v, lo, mid, hi);
}
public static void sortX(Comparable[] v){//使用了插入排序的归并排序
int N=v.length;
temp=new Comparable[N];
int lo=0;
int hi=N-1;
sort_insert(v, lo, hi);
}
public static void sort_insert(Comparable[] v,int lo,int hi){//在子数组长度小于5时使用插入排序
if(lo>=hi) return;
if(hi-lo+1<5){
InsertSort.sort(v, lo, hi);
return;
}
int mid=lo+(hi-lo)/2;
sort(v, lo, mid);
sort(v, mid+1, hi);
merge(v, lo, mid, hi);
}
public static void merge(Comparable[] v,int lo,int mid,int hi){//归并排序
for(int i=lo;i<=hi;i++){
temp[i]=v[i];//将要排序的部分复制到辅助数组中。排序结果存入v。
}
int i=lo;
int j=mid+1;
for(int k=lo;k<=hi;k++){
if(i>mid) v[k]=temp[j++];//左边的已经取完,直接取右边的
else if(j>hi) v[k]=temp[i++];//右边的已经取完,直接取左边的
else if(less(temp[i], temp[j])) v[k]=temp[i++];//如果右边的小于左边的,右边的进入结果数组
else v[k]=temp[j++];//左边的进入结果数组
}
}
public static boolean less(Comparable a,Comparable b){
return a.compareTo(b)<0;
}
public static void show(Comparable[] v){
StringBuffer sb=new StringBuffer();
for (int i = 0; i < v.length; i++) {
sb.append(" "+v[i]);
}
System.out.println(sb.toString());
}
public static boolean issorted(Comparable[] v) {
for (int i = 0; i < v.length - 1; i++) {
if (less(v[i + 1], v[i]))
return false;
}
return true;
}
public static void main(String[] args) {
Double[] n={1.2,3.5,8.2,0.5,1.8,2.9,3.0,4.5,0.3,0.1,5.3,2.9,4.2,8.0,7.6};
sort(n);
// sortX(n);
show(n);
System.out.println(issorted(n));
}
}
自底向上的归并排序(使用循环)
自顶向下的归并排序是将大数组分成小数组归并,最小的归并长度为1,自底向上的归并排序现将数组按长度为1、2、4……N/2进行归并。
/**
* 自底向上的归并排序
* @author XY
*
*/
@SuppressWarnings("rawtypes")
public class MergeSortX {
private static Comparable[] temp;
public static void sort(Comparable[] v){
int N=v.length;
temp=new Comparable[N];
for (int size=1; size<N; size*=2) {//循环变长度
for(int lo=0;lo<=N-1 && N-1-lo+1>size;lo=lo+size+size){
merge(v, lo, lo+size-1, Math.min(lo+size+size-1,N-1));//注意右边界
}
}
}
public static void merge(Comparable[] v,int lo,int mid,int hi){
for(int i=lo;i<=hi;i++){
temp[i]=v[i];
}
int i=lo;
int j=mid+1;
for(int k=lo;k<=hi;k++){
if(i>mid) v[k]=temp[j++];
else if(j>hi) v[k]=temp[i++];
else if(less(temp[i], temp[j])) v[k]=temp[i++];
else v[k]=temp[j++];
}
}
public static boolean less(Comparable a,Comparable b){
return a.compareTo(b)<0;
}
public static void show(Comparable[] v){
StringBuffer sb=new StringBuffer();
for (int i = 0; i < v.length; i++) {
sb.append(" "+v[i]);
}
System.out.println(sb.toString());
}
public static void show(Comparable[] v,int lo,int hi){
StringBuffer sb=new StringBuffer();
for (int i = lo; i <= hi; i++) {
sb.append(" "+v[i]);
}
System.out.println(sb.toString());
}
public static boolean issorted(Comparable[] v) {
for (int i = 0; i < v.length - 1; i++) {
if (less(v[i + 1], v[i]))
return false;
}
return true;
}
public static void main(String[] args) {
Double[] n={1.2,3.5,8.2,0.5,1.8,2.9,3.0,4.5,0.3,0.1,5.3,6.5,4.2,8.0,7.6,2.9};
sort(n);
show(n);
System.out.println(issorted(n));
}
}