1. 程式人生 > >歸併排序(自頂向下) java版本

歸併排序(自頂向下) java版本

該演算法思路如下:

1、新開闢一個輔助陣列,方便歸併時使用,由於歸併時需要輔助空間,又防止在每次歸併時都開闢一個新陣列,所以提前申請一個同樣大小空間的陣列

2、將整個陣列二分,分別遞迴排序前半部分與後半部分,之後將兩部分歸併

以上步驟二是分治法的典型思路

當我們的排序不斷遞迴下去時,直到被拆分的陣列中只有一個元素時,這時候陣列便是有序的,之後和另一個相鄰元素歸併,。。直到前半部分有序,後半部分同樣遞迴與歸併,之後前半部分與後半部分歸併,形成整個有序的一個數組。

歸併的思路確實是相當精妙的。。。

以下為java版本的實現

public class merge_sort {
	//貴賓用的輔助陣列
	private static int[] aux;
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] intarry={0,12,1,90,2,11,9,4,6,13,5,3,33};
		aux = new int[intarry.length];
		mergesort(intarry,0,intarry.length-1);
		for(int i:intarry){
			System.out.print(i);
			System.out.print(",");
		}
	}
	
	public static void mergesort(int[] intarry,int low,int high){
		if(high==low) return;
		int mid=low+(high-low)/2;
		mergesort(intarry,low,mid);
		mergesort(intarry,mid+1,high);
		merge(intarry,low,mid,high);
	}
	/***
	 * 原地歸併
	 * @param intarrya 陣列
	 * @param low 歸併頭節點
	 * @param mid 歸併的分割點
	 * @param high 歸併的尾節點
	 * 
	 */
	public static void merge(int[] intarry,int low,int mid,int high){
		int i=low;
		int j=mid+1;
		for(int k=low;k<=high;k++){
			aux[k]=intarry[k];
		}
		for(int k=low;k<=high;k++){
			if(i>mid){
				intarry[k] = aux[j++];
			}else if(j>high){
				intarry[k] = aux[i++];
			}else if(aux[i]<aux[j]){
				intarry[k]=aux[i++];
			}else{
				intarry[k]=aux[j++];
			}
		}
	}

}
其實歸併的實現還有一種自底向上的實現與自頂向下的區別如下

自頂向下:

亂序5,4,2,1,6,3>>4,5,2,1,6,3>>4,5,1,2,6,3>>1,2,4,5,6,3>>1,2,4,5,3,6>>1,2,3,4,5,6

自底向上

亂序5,4,2,1,6,3>>4,5,2,1,6,3>>4,5,1,2,6,3>>4,5,1,2,3,6>>1,2,4,5,3,6>>1,2,3,4,5,6