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