JAVA基本算法詳細圖解---歸併排序

今天來搞一搞歸併(合併)排序

基本思想

歸併排序的主要實現思想是分治策略,

先拋出兩個問題,大家在讀的過程中分析下爲什麼歸併排序滿足下面這兩點

1、時間複雜度:T(n)= O(nlogn)

2、合併排序算法是漸進最優算法。

將待排序的數組分爲大致相等的兩部分,分別對這兩部分進行排序,最終將兩個排好序的數組合併成一個有序的數組。

接下來我們先來看實現代碼,如果可以看明白代碼,說明你已經瞭解了歸併算法了。看的時候有疑問也不要緊,我們下面會進行詳細的分解詳細描述。

代碼實現(遞歸)

 /**
     * 歸併排序(遞歸寫法)
     * @param nums 需要排序的數組
     * @param left 需排序的起始下標
     * @param right 需排序的結束下標
     * @return 結果(有序數組)
     */
    public int[] mergeSort(int[] nums,int left,int right){
        
        //如果 數組爲空或者數組的元素數爲1,則認爲該數組已經是有序的
        if(left < right){
            //1、找數組中間位置下標
            int mid = (left + right)/2;
            //2、對左半部分排序
            mergeSort(nums,left,mid);
            //3、對有右半部分排序
            mergeSort(nums,mid+1,right);
            //4、合併
            merge(nums,left,mid,right);
        }
        return nums;
    }
    
    /**
     * 兩個有序數組合並
     * @param nums 原數組
     * @param left 數組起始下標
     * @param mid 數組中間下標
     * @param right 數組結束下標
     */
    public void merge(int[] nums,int left,int mid,int right){
        
        //1、數組一的起始下標
        int i = left;
        //2、數組二的起始下標
        int j = mid +1;
        
        //3、需要一個臨時數組
        int[] temp = new int[right - left +1];
        int k = 0;
        
        //4、順序比較兩個數組,並將小的值放到臨時數組中,直到其中一個數組中的元素都放入臨時數組中
        while (i<=mid && j<=right){
            if(nums[i] <= nums[j]){
                temp[k++] = nums[i++];
            }else {
                temp[k++] = nums[j++];
            }
        }
        //5、將數組一剩餘的元素放入臨時數組
        while (i<=mid ){
            temp[k++] = nums[i++];
        }
        //6、將數組二剩餘的元素放入臨時數組
        while (j<=right){
            temp[k++] = nums[j++];
        }
    
        //7、將臨時數組中的元素copy到原數組中
        for (int l = 0; l < temp.length; l++) {
            nums[left+l] = temp[l];
        }
    }

 

上面註釋已經將步驟一一都寫了,如果有疑問我們看下詳細的圖解

大家可以思考下  非遞歸方式如何實現,以及自然合併排序算法

注:自然合併排序會在下篇文章中介紹,

參考 

算法設計與分析  第3版__王曉東編著_北京:清華大學出版社_P330_2014.02_13476624

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章