歸併排序(MERGE-SORT)是創建在歸併操做上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個很是典型的應用。將已有序的子序列合併,獲得徹底有序的序列;即先使每一個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱爲二路歸併。歸併排序是一種穩定的排序方法。
<!--more-->java
前面有介紹,這裏依然不作介紹算法
核心思想:不斷的將大的數組分紅兩個小數組,直到不能拆分爲止,即造成了單個值。此時使用合併的排序思想對已經有序的數組進行合併,合併爲一個大的數據,不斷重複此過程,直到最終全部數據合併到一個數組爲止。數組
我在網上看到一大神寫的關於 歸併排序的圖解,很清楚明瞭。能夠借鑑一下: 【圖解】歸併排序ide
圖解歸併-動態
spa
Java程序是網上獲得哪位大神提供的。scala
public static void main(String[] args) { int[] data = {8, 4, 5, 7, 1, 3, 6, 2}; mergeSort(data); System.out.println(Arrays.toString(data)); } public static void mergeSort(int[] arr) { sort(arr, 0, arr.length - 1); } public static void sort(int[] arr, int L, int R) { if (L == R) { return; } int mid = L + ((R - L) >> 1); sort(arr, L, mid); sort(arr, mid + 1, R); merge(arr, L, mid, R); } public static void merge(int[] arr, int L, int mid, int R) { int[] temp = new int[R - L + 1]; int i = 0; int p1 = L; int p2 = mid + 1; // 比較左右兩部分的元素,哪一個小,把那個元素填入temp中 while (p1 <= mid && p2 <= R) { temp[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++]; } // 上面的循環退出後,把剩餘的元素依次填入到temp中 // 如下兩個while只有一個會執行 while (p1 <= mid) { temp[i++] = arr[p1++]; } while (p2 <= R) { temp[i++] = arr[p2++]; } // 把最終的排序的結果複製給原數組 for (i = 0; i < temp.length; i++) { arr[L + i] = temp[i]; } }
def main(args: Array[String]): Unit = { var left: List[Int] = List( 4, 5, 7, 8 ) var right: List[Int] = List(1, 2, 3, 6) val ints: List[Int] = merge(left, right) println(ints) } def merge(left: List[Int], right: List[Int]): List[Int] = (left, right) match { case (Nil, _) => right case (_, Nil) => left case (x :: xTail, y :: yTail) => if (x <= y) x :: merge(xTail, right) else y :: merge(left, yTail) }
在歸併以前,首先先要對兩個數組作排序,要保證他們兩個有序,而後在進行歸併。以前的有序的過程可使用快速排序算法。code
在歸併中,通常會使用 快排 + 歸併 來完成一個數組的排序。blog
時間複雜度:O(nlogn)排序
空間複雜度:O(N),歸併排序須要一個與原數組相同長度的數組作輔助來排序rem