1. 程式人生 > >常用排序算法專題—歸並排序

常用排序算法專題—歸並排序

vid 行合並 按順序 二叉樹 簡單的 mergesort 算法 main str

歸並排序
歸並排序(Merge Sort)是建立在歸並操作上的一種有效的排序算法,該算法是采用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合並,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合並成一個有序表,稱為二路歸並。

基本思路
技術分享圖片

分而治之
在計算機科學中,分治法是一種很重要的算法。字面上的解釋是“分而治之”,就是把一個復雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題,直到最後子問題可以簡單的直接求解,原問題的解即子問題的解的合並。

我們可以看到上圖中,待排序數組為{4,8,2,7,1,6,3,5},我們先將它們分解成{4,8,2,7}和{1,6,3,5}兩部分,將這兩部分繼續分解為{4,8}、{2,7}和{1,6}、{3、5};以此類推,分解的過程完成。接著我們將4,8,2,7,1,6,3,5兩兩排序合並,變成{4,8}、{2,7}、{1,6}、{3、5},緊接著繼續將以上四部分兩兩排序合並,變成{2,4,7,8}和{1,3,5,6},最後再將這兩部分排序合並,排序完成。

歸並操作
歸並操作需要將兩個已經有序的子序列合並成一個有序序列,我們選擇圖中的{2,4,7,8}和{1,3,5,6}為例,它是怎麽合並成一個有序數列呢?
我們先重新申請一個能容納兩個數組歸並的空間(命名temp的數組),兩個哨兵指針 i 和 j 分別指向兩個數組的開頭;我們對比兩個指針所指向數據的大小,將小的數據移向temp數組,指向該數據的指針向後移動。
技術分享圖片

技術分享圖片

註:我們發現 j 指針已經指向結尾,那麽把前一個數組的剩余數據按順序移到temp數組。
技術分享圖片

此時兩個已經有序的子序列合並成了一個有序序列。

JAVA 代碼

package DataStructure;
public class MergeSort {

public static void sort(int[] arr, int low, int high, int[] temp) {
if (low < high) {
int mid = (low + high) / 2;
sort(arr, low, mid, temp);
sort(arr, mid + 1, high, temp);
merge(arr, low, mid, high, temp); // 對兩個子數組進行合並操作
}
}
private static void merge(int[] arr, int low, int mid, int high, int[] temp) {
int tempPoint = 0; // temp數組指針
int i = low; // i指針
int j = mid + 1; // j指針
while (i <= mid && j <= high)
if (arr[i] <= arr[j])
temp[tempPoint++] = arr[i++];
else
temp[tempPoint++] = arr[j++];
while (i <= mid)
temp[tempPoint++] = arr[i++]; // 左邊剩余的填充至temp數組中
while (j <= high)
temp[tempPoint++] = arr[j++]; // 右邊剩余的填充至temp數組中

int t = 0;
while (low <= high) // 返回至原數組
arr[low++] = temp[t++];
}
public static void main(String[] args) {
int[] arr = { 4, 8, 2, 7, 1, 6, 3, 5 };
int[] temp = new int[arr.length];
sort(arr, 0, arr.length - 1, temp);
for (int n : arr)
System.out.print(n + " ");
}
}
時間復雜度
歸並排序是穩定排序,它也是一種十分高效的排序,上圖中可看出,每次合並操作的平均時間復雜度為O(n),而完全二叉樹的深度為O(logn)。總平均時間復雜度為O(nlogn)。而且,歸並排序的最好、最壞、平均時間復雜度均為O(nlogn)。

喜歡的點點關註,點點贊。

對Java技術,架構技術感興趣的同學,歡迎加QQ群585550789,一起學習,相互討論。

群內已經有小夥伴將知識體系整理好(源碼,筆記,PPT,學習視頻),歡迎加群領取。

常用排序算法專題—歸並排序