1. 程式人生 > >【圖解演算法】排序演算法——歸併排序

【圖解演算法】排序演算法——歸併排序

0.什麼是歸併排序(Merge sort)?

是建立在歸併操作上的一種有效的排序演算法,效率為O(n log n)。1945年由約翰·馮·諾伊曼首次提出。該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用,且各層分治遞迴可以同時進行。(from zh.wikipedia.org

我對歸併排序的理解是——分而治之,就是一個問題看起來很複雜,那就將他分開處理,這也是遞迴的思想; 就拿排序這件事件來說,對一個數組的排序,我們可以將他分成兩個陣列來處理,再對這兩個陣列同樣的道理來處理,將他們分別分成兩個陣列來處理…… 直到陣列無法再細分下去(即陣列的長度為1,只有一個元素的陣列肯定是有序的),分為之後的陣列進行合併操作,向上整合整個陣列,最後到達得到一個有序的陣列的目的。

可能這樣說得很抽象,我們一起來看歸併排序的動態處理元素的圖例:
這裡寫圖片描述

看著圖的同時再來看一看具體的程式碼實現過程:

    public static void main(String [] args){
        int[] t = {18,7,8,6,33,2,9,1};
        mergSort(t,0,7);
        for (int i = 0;i<t.length;i++)
            System.out.print(t[i] + "\t");
    }


    public static void mergSort(int [] arr,int
l,int r){ if(l>=r) return; int mid = (l+r)/2; //遞迴二分 將陣列分為 [左,中],(中,右] mergSort(arr,l,mid); mergSort(arr,mid+1,r); //歸併排序 int aux[] = new int[r-l+1]; //這裡弄一個要處理的陣列副本 長度是 R-L+1 for (int i =l;i<=r ;i++) //副本陣列從 L 開始,所以與原陣列存在一個 L 的偏移量 aux[i-l] = arr[i]; int
i = l,j = mid+1; //i記錄左邊元素的下標位置 j記錄右邊元素的下標位置 for (int k =l;k <= r; k++){ //k記錄 arr 的下標位置 if(i >mid){ arr[k] = aux[j-l]; j++; }else if(j >r){ arr[k] = aux[i-l]; i++; }else if(aux[i-l] < aux[j-l]){ arr[k] = aux[i-l]; i++; }else{ arr[k] = aux[j-l]; j++; } } }

程式輸出:

1 2 6 7 8 9 18 33

圖解演算法目錄