1. 程式人生 > >“深入理解”—歸併排序演算法

“深入理解”—歸併排序演算法


歸併排序:

  歸併排序 (merge sort) 是一類與插入排序、交換排序、選擇排序不同的另一種排序方法。歸併的含義是將兩個或兩個以上的有序表合併成一個新的有序表。

如圖所示:

import java.util.Arrays;

public class Test {  
    // 歸併排序的實現  
    public static void main(String[] args) {  
  
        int[] nums = { 2, 7, 8, 3, 1, 6, 9, 0, 5, 4, -3};  
        System.out.println(Arrays.toString(nums));  
        sort(nums, 0, nums.length-1);  
        System.out.println(Arrays.toString(nums));  
    }
    
    /** 
     * 歸併排序 
     * 簡介:將兩個(或兩個以上)有序表合併成一個新的有序表 即把待排序序列分為若干個子序列,
     *     每個子序列是有序的。然後再把有序子序列合併為整體有序序列 
     * 時間複雜度為O(nlogn) 
     * 穩定排序方式 
     * @param nums 待排序陣列 
     * @return 輸出有序陣列 
     */  
    public static int[] sort(int[] nums, int low, int high){
    	int mid = (low+high)/2;
    	if(low<high){
    		// 處理左邊
    		sort(nums, low, mid);
    		// 處理右邊
    		sort(nums, mid+1, high);
    		// 左右歸併
    		merge(nums, low, mid, high);
    	}
    	return nums;
    }
    private static void merge(int[] nums, int low, int mid, int high) {
	// 定義一個輔助陣列,所以該演算法的空間複雜度為O(n)
    	int[] temp = new int[high-low+1];
    	int i = low;
    	int j = mid+1;
    	int k = 0;
    	// 找出較小值元素放入temp陣列中
    	while(i<=mid && j<=high){
    		if(nums[i]<nums[j])
    			temp[k++] = nums[i++];
    		else
    			temp[k++] = nums[j++];
    	}
    	// 處理較長部分
    	while(i<=mid){
    		temp[k++] = nums[i++];
    	}
    	while(j<=high){
    		temp[k++] = nums[j++];
    	}
    	// 使用temp中的元素覆蓋nums中元素
    	for (int k2 = 0; k2 < temp.length; k2++) {
			nums[k2+low] = temp[k2];
		}
	}
}  



演算法分析

(1)穩定性
      歸併排序是一種穩定的排序。

(2)儲存結構要求
     可用順序儲存結構。也易於在連結串列上實現。

(3)時間複雜度
     對長度為n的檔案,需進行 趟二路歸併,每趟歸併的時間為O(n),故其時間複雜度無論是在最好情況下還是在最壞情況下均是O(nlgn)

(4)空間複雜度
     需要一個輔助向量來暫存兩有序子檔案歸併的結果,故其輔助空間複雜度為O(n)

如果對你有幫助,記得點贊哦~歡迎大家關注我的部落格,可以進群366533258一起交流學習哦~