演算法筆記 歸併排序 Merge Sort

2021-09-16 22:04:40 字數 2180 閱讀 3191

1. 把陣列分成兩部分。

2. 遞迴地排序這兩個陣列。

3. 將陣列的兩部分合併。

目標:given two sorted subarrays a[lo] to a[mid] and a[mid+1] to a[hi], replace with sorted subarray a[lo] to a[hi]

private static void merge(comparable a, comparable aux, int lo, int mid, int hi)

assert issorted(a, lo, hi); // postcondition: a[lo..hi] sorted

}

public class merge

private static void sort(comparable a, comparable aux, int lo, int hi)

public static void sort(comparable a)

}

與後面要講到的快速排序(quick sort)相比,歸併排序演算法的**實現可以說是十分簡單和容易理解的。歸併排序的過程就是乙個先分再合的過程。

merge函式能成功執行的前提是參與merge的兩個陣列是有序的,而sort函式則似乎是什麼都沒有做,僅僅是把陣列分成兩部分再交給merge。通過這兩個函式,可以成功進行排序的原因是單個元素一定是有序的,我們不斷地分割再分割,最後一定會得到長度為1的陣列,從這裡開始,merge函式開始發揮作用,兩個長度為1的陣列合併為長度為2的陣列,再不斷合成更大的陣列,最終完成整個陣列的排序。

時間複雜度

空間複雜度

通過演算法的**實現,我們很容易發現,歸併排序需要乙個額外的大小為n的陣列去輔助我們排序。

1. 對於小陣列直接排序

在歸併排序中,我們產生了太多長度極小的陣列,事實上,在陣列長度小於一定值之後(大約可以取7),我們可以直接進行排序,這樣可以獲得一定的提公升。()

private static void sort(comparable a, comparable aux, int lo, int hi)

int mid = lo + (hi - lo) / 2;

sort (a, aux, lo, mid);

sort (a, aux, mid+1, hi);

merge(a, aux, lo, mid, hi);

}

2. 及時停止排序舉個例子,我們想要把乙個陣列從小到大排序,假設我們已經完成了對陣列左半部分與右半部分的排序,如果我們這個時候我們發現,左半部分的最大值,小於右半部分的最小值,那麼顯然,整個陣列已經排好序了,這個時候,我們沒有必要進行merge操作。

private static void sort(comparable a, comparable aux, int lo, int hi)

3. 避免陣列的來回拷貝這個操作很有趣,要我寫,肯定出錯誤。前面提到歸併排序需要乙個輔助陣列,而且從**中,我們可以看到我們需要把原陣列中的元素不斷拷貝到輔助陣列中去。那麼我們能不能避免這種操作呢?答案是肯定的,解決方案是不再區分原陣列和輔助陣列,兩個陣列交替使用。這個操作可謂是藝高人膽大。

private static void merge(comparable a, comparable aux, int lo, int mid, int hi)

}private static void sort(comparable a, comparable aux, int lo, int hi)

這個是歸併排序的非遞迴實現方法,但是速度上會比遞迴的要慢一些。

public class mergebu

public static void sort(comparable a)

}

插入排序和歸併排序是穩定的,而選擇排序和希爾排序是不穩定的。

《演算法筆記》 歸併排序

歸併操作,也叫歸併演算法,指的是將兩個順序序列合併成乙個順序序列的方法,平均時間複雜度為o nlogn 歸併排序的實現分為遞迴實現與非遞迴 迭代 實現。如 設有數列 初始狀態 6,202,100,301,38,8,1 第一次歸併後 比較次數 3 第二次歸併後 比較次數 4 第三次歸併後 比較次數 4...

演算法筆記 歸併排序

平均時間複雜度o nlogn 對於乙個待排序的陣列,我們可以先遞迴地將它分成兩半分別排序,然後將結果歸併起來。簡單的說就是把乙個陣列分成兩半,然後把這兩半分別排好序,最後將這兩部分合在一起進行排序,實際情況下,分成兩部分陣列的排序仍然是採用歸併的方式,所以我們會使用到遞迴的思想來操作。前提是待排序陣...

演算法筆記 歸併排序

很簡單的乙個排序,先通過遞迴劃分區間到最小 因為乙個元素具有單調性 然後再合併兩個單調區間為乙個單調區間,具體看 模板 void merge int l,int m,int r else temp k a i while i m temp k a i while j r temp k a j for...