排序算法之歸併排序

1、分治法的思想
java

把複雜的問題分解,再分解,成爲很小的問題,解決這些小問題以後合併,再合併。這就是分治法的思想。算法

一般分治法是遞歸的。優化

2、歸併排序code

歸併排序就是利用分治法,把無序的數列拆分紅多個子數列,子數列再拆分紅多個子數列,直至只子數列只有2個數,而後排序,合併,再排序,在合併。。。直到只剩一個有序的數列。排序

歸併排序算法的核心就是:兩個各自有序的數列合併成一個徹底有序的數列。這個過程能夠說很簡單,就是從兩個數列開頭選出最小的數,放入第三個數列中,而後較小的數的指標後移,繼續重複操做。直到其中一個數列所有被放入隊列中,此時另外一個隊列剩下的所有數放入第三個數列。遞歸

歸併排序的時間複雜度是O(nlgn)隊列

如圖所示:class


3、Java代碼實現im

public class MergeSort {
    public static void main(String[] args) {
        int a[] = {5,3,2,8,7,6,10,20,30,11,22,33,44,100,60,200};

        mergeSort(a, 0, a.length - 1);

        for (int i : a) {
            System.out.println(i);
        }
    }

    //遞歸拆分數列
    public static void mergeSort(int[] a, int low, int high) {
        int middle = (low + high) / 2;
        if (low < high) {
            mergeSort(a, low, middle);
            mergeSort(a, middle + 1, high);
            merge (a, low, middle, high);
        }
    }

    //合併兩段有序數列
    public static void merge(int[] a, int low, int middle, int high) {
        int n1 = middle - low + 1;
        int n2 = high - middle;

        int[] l = new int[n1];
        int[] r = new int[n2];

        for (int i = low, j = 0; i <= middle; i++, j++) {
            l[j] =a[i];
        }

        for (int i = middle + 1, j= 0; i <= high; i++, j++) {
            r[j] = a[i];
        }

        int i = 0;
        int j = 0;
        int k = low;
        while(i < n1 || j < n2) {
            if (i < n1 && j < n2) {
                if (l[i] < r[j]) {
                    a[k++] = l[i];
                    i++;
                }else {
                    a[k++] = r[j];
                    j++;
                }
            } else if (i < n1) {
                a[k++] = l[i];
                i++;
            } else if (j < n2) {
                a[k++] = r[j];
                j++;
            }
        }
    }
}

4、思考歸併排序的優化。static

歸併排序的時間複雜度是nlgn ,插入排序的時間複雜度是n^2。

歸併排序在n較小的時候是不如插入排序的。因此咱們可使用歸併排序劃分,到必定數的時候使用插入排序進行底層的排序,這樣優化起來就很是合理了。

相關文章
相關標籤/搜索