(戀上資料結構筆記):歸併排序(Merge Sort)
目錄
歸併排序
- 1945年由約翰·馮·諾伊曼(John von Neumann)首次提出。
- 執行流程
- ① 不斷地將當前序列平均分割成 2 個子序列
- 直到不能再分割(序列中只剩 1 個元素)
- ② 不斷地將 2 個子序列合併成一個有序序列
- 直到最終只剩下 1 個有序序列
序列分割-divide
protected void sort() { leftArray = (T[]) new Comparable[array.length >> 1]; sort(0, array.length); } / * 對 [begin, end) 範圍的資料進行歸併排序 */ private void sort(int begin, int end){ if(end - begin < 2) return; // 至少要2個元素 int mid = (begin + end) >> 1; sort(begin, mid); // 歸併排序左半子序列 sort(mid, end); // 歸併排序右半子序列 merge(begin, mid, end); // 合併整個序列 }
序列合併-merge
原地合併-merge
- 將兩個序列合併時,不一定要合併到新空間,可以合理的利用原空間實現原地合併。
- 例如:
- 將 array的左半部分[begin, mid),備份到 leftArray 中;
- 然後將 leftArray 視為左子序列,arrary的右半部分[mid, end] 視為右子序列;
- 將左子序列和右子序列合併到 array 中。
- 合併過程
左邊先結束
右邊先結束
程式碼實現
public class MergeSort <T extends Comparable<T>> extends Sort<T> { private T[] leftArray; @Override protected void sort() { // 準備一段臨時的陣列空間, 在merge操作中使用 leftArray = (T[])new Comparable[array.length >> 1]; sort(0, array.length); } /** * 對 [begin, end) 範圍的資料進行歸併排序 */ private void sort(int begin, int end){ if(end - begin < 2) return; // 至少要2個元素 int mid = (begin + end) >> 1; sort(begin, mid); // 歸併排序左半子序列 sort(mid, end); // 歸併排序右半子序列 merge(begin, mid, end); // 合併整個序列 } /** * 將 [begin, mid) 和 [mid, end) 範圍的序列合併成一個有序序列 */ private void merge(int begin, int mid, int end){ int li = 0, le = mid - begin; // 左邊陣列(基於leftArray) int ri = mid, re = end; // 右邊陣列(array) int ai = begin; // array的索引 // 備份左邊陣列到leftArray for(int i = li; i < le; i++){ leftArray[i] = array[begin + i]; } // 如果左邊還沒有結束 while(li < le){ // li == le 左邊結束, 則直接結束歸併 if(ri < re && cmp(array[ri], leftArray[li]) < 0){ // cmp改為<=0會失去穩定性 array[ai++] = array[ri++]; // 右邊<左邊, 拷貝右邊陣列到array }else{ array[ai++] = leftArray[li++]; // 左邊<=右邊, 拷貝左邊陣列到array } } } }
- 測試
複雜度分析
【常見的遞推式和複雜度】
相關文章
- 演算法與資料結構系列 ( 七 ) - 歸併排序- Merge Sort演算法資料結構排序
- 排序演算法之「歸併排序(Merge Sort)」排序演算法
- 歸併排序演算法(merge_Sort)排序演算法
- (戀上資料結構筆記):計數排序、基數排序 、桶排序資料結構筆記排序
- 資料結構:歸併排序(非遞迴)資料結構排序遞迴
- 【資料結構與演算法】歸併排序資料結構演算法排序
- 資料結構與演算法——排序演算法-歸併排序資料結構演算法排序
- 資料結構學習筆記-堆排序資料結構筆記排序
- 演算法與資料結構高階排序演算法之歸併排序演算法資料結構排序
- Sort排序專題(7)歸併排序(MergeSort)(C++實現)排序C++
- 演算法與資料結構基礎 - 排序(Sort)演算法資料結構排序
- 【c++】結構體sort排序C++結構體排序
- 《戀上資料結構與演算法》筆記(九):二叉搜尋樹 II資料結構演算法筆記
- 【Java資料結構與演算法】第八章 快速排序、歸併排序和基數排序Java資料結構演算法排序
- 資料結構學習筆記-簡單選擇排序資料結構筆記排序
- 資料結構筆記資料結構筆記
- Insertion Sort and Merge Sort
- 資料結構第九節(排序(上))資料結構排序
- 演算法:排序連結串列:歸併排序演算法排序
- 歸併排序排序
- 快速排序&&歸併排序排序
- 資料結構筆記——概述資料結構筆記
- 資料結構筆記——棧資料結構筆記
- 演算法與資料結構系列 ( 六 ) - 氣泡排序法- Bubble Sort演算法資料結構排序
- 演算法與資料結構系列 ( 四 ) - 插入排序法- Insert Sort演算法資料結構排序
- 演算法與資料結構系列 ( 三 ) - 選擇排序法- Select Sort演算法資料結構排序
- 【資料結構與演算法】高階排序(希爾排序、歸併排序、快速排序)完整思路,並用程式碼封裝排序函式資料結構演算法排序封裝函式
- Polyphase Merge Sort
- 淺談歸併排序:合併 K 個升序連結串列的歸併解法排序
- 四、歸併排序 && 快速排序排序
- java歸併排序Java排序
- [C++]歸併排序(連結串列描述)C++排序
- 筆記:大話資料結構筆記資料結構
- 資料結構學習筆記資料結構筆記
- 資料結構筆記——佇列資料結構筆記佇列
- [做題筆記] 資料結構筆記資料結構
- 資料結構與演算法——歸併排序: 陣列&連結串列&遞迴&非遞迴解法全家桶資料結構演算法排序陣列遞迴
- 從零開始學資料結構和演算法 (五) 分治法 (二分查詢、快速排序、歸併排序)資料結構演算法排序