1. 程式人生 > >排序演算法(Java隨筆)—歸併排序

排序演算法(Java隨筆)—歸併排序

歸併排序(Merge Sort):將多個有序資料表合併為一個有序資料表,如果被合併的資料表只有兩個,則叫二路歸併。

二路歸併排序的原理步驟:

  1. 將長度為n的原資料表分割為n個長度為1的子表,兩兩合併得到n/2個長度為2的有序子表
  2. 將長度為2的有序子表兩兩合併得到n/4個長度為4的有序子表
  3. 重複以上步驟,直到最後的子表長度為n,排序完成

原理總結:先通過遞迴分解序列,再有序的合併序列即完成了歸併。

歸併排序演算法例項——程式碼實現:

//歸併排序(分兩步):先遞迴,再合併(將陣列遞迴分解,再進行排序合併)
	//1、合併陣列
	void mergeArray(int[] data,int start,int mid,int end){
		/*
		 * @param data[] 需要被排序的陣列
		 * @param start 陣列的開始
		 * @param end 陣列的結尾
		 */
		int[] temp=new int[end-start+1];//存放排序好的陣列,陣列大小為當前參與排序的資料個數
		int s=start;//陣列左引用
		int e=mid+1;//陣列右引用
		int k=0;//陣列temp[]的下一個位置的指標,每存放一個數據,k增一
		//左右合併排序
		while(s<=mid&&e<=end){
			if(data[s]<=data[e]){
				temp[k++]=data[s++];
			}else{
				temp[k++]=data[e++];
			}
		}
		//合併陣列左邊剩餘陣列
		while(s<=mid){
			temp[k++]=data[s++];
		}
		//合併陣列右邊剩餘陣列
		while(e<=end){
			temp[k++]=data[e++];
		}
		//以排序好的部分資料覆蓋掉原陣列中的資料
		for(int i=0;i<temp.length;i++){
			data[start+i]=temp[i];
		}
	}
	//2、遞迴分解陣列(首先將陣列遞迴為長度為1的序列,然後依次出棧長度為2,4...)
	/*
	 * 將陣列遞迴分解為長度為1後、通過合併陣列將相鄰兩個資料變為有序數列(排序)
	 * 如第一個資料為23、第二個資料為12、合併後第一個資料為12、第二個資料為23
	 * 然後再出棧長度為2的序列、通過合併陣列將其變為有序序列...
	 */
	int[] mergeSort(int[] data,int start,int end){
		int mid=(end-start)/2+start;
		if(start<end){
			//左遞迴
			mergeSort(data,start,mid);
			//右遞迴
			mergeSort(data,mid+1,end);
			//合併陣列
			mergeArray(data,start,mid,end);
		}
		return data;
	}

執行測試:

// 歸併排序演算法測試
	public static void main(String[] args) {
		int[] data = new int[] {9,4,6,8,7,1};
		SortSuanFa sf = new SortSuanFa();
		data = sf.mergeSort(data, 0, data.length-1);
		System.out.println(Arrays.toString(data));
	}

執行結果:
[1, 4, 6, 7, 8, 9]