1. 程式人生 > >【資料結構】歸併排序

【資料結構】歸併排序

歸併排序的基本思想是:將兩個(或以上)的有序表組成新的有序表。

更實際的意義:可以把一個長度為n的無序序列看成是n個長度為1的有序子序列,首先做兩兩歸併,得到\left \lceil n/2 \right \rceil個長度為2的子序列;再做兩兩歸併,...,如此重複,直到最後得到一個長度為n的有序序列。

例:關鍵字序列T=(21, 25, 49, 25*, 93, 62, 72, 08, 37, 16, 54),請給出歸併排序的具體實現過程。

len = 1 :  21, 25, 49, 25*,93, 62, 72, 08, 37, 16, 54

len = 2:21  25, 25* 49, 62 93, 08 72, 16 37, 54

len = 4:21 25 25* 49, 08 62 72 93, 16 37 54

len = 8:08 21 25 25* 49 62 72 93, 16 37 54

len = 16:08 16 21 25 25* 37 49 54 62 72 93

整個歸併排序僅需\left \lceil nlog2n \right \rceil

歸併排序實現的程式碼:

public class arrayMergeSort {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] arr = {21, 25, 49, 25, 93, 62, 72, 8, 37, 16, 54};
		mergeSort(arr, 0, arr.length - 1);
		for(int i=0; i<arr.length; i++) {
			System.out.print(arr[i]+" ");
		}
	}
	
	public static void mergeSort(int[] array, int low, int high) {
		int mid = (low + high) / 2;
		if(low < high) {
			// 左邊
			mergeSort(array, low, mid);
			// 右邊
			mergeSort(array, mid + 1, high);
			// 左右歸併
			merge(array, low, mid, high);
		}
		
	}
	
	public static void merge(int[] array, int low, int mid, int high) {
	       int[] temp = new int[high - low + 1];
	        int i = low;// 左指標
	        int j = mid + 1;// 右指標
	        int k = 0;
	        // 把較小的數先移到新陣列中
	        while (i <= mid && j <= high) {
	            if (array[i] < array[j]) {
	                temp[k++] = array[i++];
	            } else {
	                temp[k++] = array[j++];
	            }
	        }
	        // 把左邊剩餘的數移入陣列
	        while (i <= mid) {
	            temp[k++] = array[i++];
	        }
	        // 把右邊邊剩餘的數移入陣列
	        while (j <= high) {
	            temp[k++] = array[j++];
	        }
	        // 把新陣列中的數覆蓋nums陣列
	        for (int k2 = 0; k2 < temp.length; k2++) {
	        	array[k2 + low] = temp[k2];
	        }
	}

}

歸併排序演算法分析:

  • 時間效率:O(nlog2n)

一趟歸併排序的操作是:呼叫【n / 2h】次演算法merge將陣列中前後相鄰且長度為h的有序段進行兩兩歸併,得到前後相鄰長度為2h的有序段,並存放在輔助陣列中,整個歸併排序需要進行【log2n】趟,所以演算法總的時間複雜度為O(nlog2n)。

  • 空間效率:O(n)

因為需要一個與原始序列同樣大小的輔助序列。這正是此演算法的缺點。

  • 穩定性:穩定