# Merge Sort 合併排序法 ###### tags: `LeetCode` `sort` `merge sort` :::info :pushpin: 合併排序法採用了分治法 ( Divide and Conquer ) 概念,將陣列對半拆開,拆到小陣列只剩一個元素,拆開之後,排序再合併。它的時間複雜度是 $O(nlogn)$。 ::: --- {%youtube JSceec-wEyw %} ## 一、步驟觀察 * 將陣列對半拆分至剩一個元素 ( Divide,並使用到 ==Recursive 的概念== ) * 針對相鄰兩個陣列做完比較後,完成排序與合併 ( Conquer ) ![](https://i.imgur.com/zcJi8Ho.gif) ( 圖片來源 wiki ) ## 二、實際操作 ### 使用哪種資料結構:Array * 將 left 和 right 作為陣列兩端的索引 * 初始化 left l 等於 0 ; right r 等於 arr.length-1 * 如果 r > l,可以拆分的情況 * 找出中間點,將陣列對半拆開 * 呼叫 mergeSort( ) 處理左邊陣列 * 呼叫 mergeSort( ) 處理右邊陣列 * 呼叫 merge( ),排序並合併兩個陣列 **邏輯:** ```1 arr <- an array of integers let len be the length of arr let left l be the beginning index of array let right r be the end index of the array func mergeSort(arr, l, r): if r > l then mid = l + (r-l)/2 meargeSort(arr, l, mid) meargeSort(arr, mid+1, r) merge() end if end func ``` **程式碼實作:** ```javascript=1 debugger // Merges two subarrays of arr[]. // First subarray is arr[l..m] // Second subarray is arr[m+1..r] function merge(arr, l, m, r) { var n1 = m - l + 1; var n2 = r - m; // Create temp arrays var L = new Array(n1); var R = new Array(n2); // Copy data to temp arrays L[] and R[] for (var i = 0; i < n1; i++) L[i] = arr[l + i]; for (var j = 0; j < n2; j++) R[j] = arr[m + 1 + j]; // Merge the temp arrays back into arr[l..r] // Initial index of first subarray var i = 0; // Initial index of second subarray var j = 0; // Initial index of merged subarray var k = l; while (i < n1 && j < n2) { if (L[i] <= R[j]) { arr[k] = L[i]; i++; } else { arr[k] = R[j]; j++; } k++; } // Copy the remaining elements of // L[], if there are any while (i < n1) { arr[k] = L[i]; i++; k++; } // Copy the remaining elements of // R[], if there are any while (j < n2) { arr[k] = R[j]; j++; k++; } } // l is for left index and r is // right index of the sub-array // of arr to be sorted */ function mergeSort(arr,l, r){ if(l>=r){ return;//returns recursively } var m =l+ parseInt((r-l)/2); mergeSort(arr,l,m); mergeSort(arr,m+1,r); merge(arr,l,m,r); } var arr = [ 12, 11, 13, 5, 6, 7 ]; mergeSort(arr, 0, arr.length - 1); ``` <!-- ## 四、優化改善 內容 --> ## 三、時間複雜度 Big O * Merge Sort is θ(nLogn) in all 3 cases ( worst, average and best ) as merge sort always divides the array into two halves and takes linear time to merge two halves. ### Drawbacks of Merge Sort * Slower comparative to the other sort algorithms for smaller tasks. * Merge sort algorithm ==requires an additional memory space of 0(n) for the temporary array==. * It goes through the whole process even if the array is sorted. --- 參考資料: * https://ithelp.ithome.com.tw/articles/10241640 * [Merge Sort - GeeksforGeeks](https://www.geeksforgeeks.org/merge-sort/) * [Merge Sort Using C, C++, Java, and Python | What is Merge Sort and Examples of it?](https://www.mygreatlearning.com/blog/merge-sort/#t2)