八大排序之歸併排序

1、基本思想數組

   歸併排序,將當前序列分紅若干個小的有序序列,而後逐個合併成更大的有序序列。這裏所謂的若干個小的有序序列便是將序列分割成n個長度爲1的序列,而後兩兩合併成長度爲二的有序序列。而後在將這長度爲二的有序序列合併爲長度爲四的有序序列。依次類推,最終達到原序列長度,這樣,排序就完成了。這實際上是歸併排序遞歸回溯過程的描述。歸併排序的正序描述能夠是這樣,將序列分紅兩個子序列,對兩個子序列進行歸併排序,而後將兩個子序列合併到原序列中。dom

2、實現步驟測試

   歸併排序,有兩個須要解決的問題:1、如何劃分子區間。2、如何合併子區間。spa

  劃分子區間:code

  這裏採用兩路歸併排序,即將當前序列劃分紅兩個子序列。blog

  合併子區間:排序

  因爲子區間是有序的,因此在合併過程當中不會有很大的複雜度,一次遍歷便可。遞歸

  思想已經陳述完畢,下面看代碼,有詳細註釋。get

3、實現代碼io

   隨機數組測試類 點擊這裏

package sort;

import sort.util.*;

public class MergingSort implements ISort{ 

    //private static int[] c = null;
    //將有序序列a[left] ~ a[middle]和a[middle+1] ~ a[right]合併到數組b中,返回數組b
    private void merge(int[] a , int left ,  int middle , int right) {
        int[] b = new int[a.length];
        for(int i = 0; i < a.length; i++) {            //將數組a複製到b中
            b[i] = a[i];
        }
        int i = left ,  j = middle + 1 ,  k = left;
        while(i <= middle && j <= right) {             //合併過程,選擇較小的,逐個賦值。
            if(b[i] < b[j]) a[k++] = b[i++];
            else a[k++] = b[j++];
        }                                              //循環結束,說明有一個有序序列已經遍歷完畢
        while(i <= middle) {a[k++] = b[i++];}          //將剩餘的部分直接複製到a數組中
        while(j <= right) {a[k++] = b[j++];}           //這兩個循環只有一個能被執行
        
    }
    
    //對a[left] ~ a[right]進行歸併排序,排序後的結果放在b[]中
    private void mergeSort(int[] a , int left , int right) {
        if(left != right) {                             //當進行歸併排序的數組只有一個元素      
            int middle = (left + right) / 2;            //劃分紅兩部分進行歸併
            mergeSort(a , left , middle);               //左邊部分進行歸併排序
            mergeSort(a , middle+1 , right);            //右邊部分進行歸併排序
            merge(a , left , middle , right);           //左右排序完成後進行合併
        }
    }
    
    public void sort(int[] array){
        mergeSort(array , 0 , array.length-1);
    }
    public static void main(String[] args) {
        int[] array = RandomArrayGenerator.getRandomArray(100 , 30);
        SortTestHelper.test(new MergingSort() , array);
    }
}

 

測試結果:

 

4、總結分析

   時間複雜度:O(n log n)   合併複雜度爲n,遞歸過程的複雜度爲log2n

  空間複雜度:O(n)             須要一個輔助數組

  穩定性:穩定。

  八大排序中其他兩個nlogn複雜度的堆排序和快速排序是不穩定的,較普通排序更快的希爾排序也是不穩定的。本文所講的歸併排序倒是穩定的,並且效率也很可觀。

  本文我的編寫,水平有限,若有錯誤,懇請指出,歡迎討論分享

相關文章
相關標籤/搜索