TypeScript實現十大排序算法之歸并排序示例詳解
目錄
- 一. 歸并排序的定義
- 二. 歸并排序的流程
- 三. 歸并排序的圖解
- 四. 歸并排序的代碼
- 五. 歸并排序的時間復雜度
- 六. 歸并排序的總結
一. 歸并排序的定義
歸并排序(merge sort)是一種常見的排序算法:
- 它的基本思想是將待排序數組分成若干個子數組。
- 然后將相鄰的子數組歸并成一個有序數組。
- 最后再將這些有序數組歸并(merge)成一個整體有序的數組。
這個算法最早出現在1945年,由約翰·馮·諾伊曼(John von Neumann)(又一個天才,現代計算機之父,馮·諾依曼結構、普林斯頓結構)首次提出。
- 當時他在為美國政 府工作,研究原子彈的問題。
- 由于當時計算機,他在研究中提出了一種高效計算的方法,這個方法就是歸并排序。
歸并排序的基本思路是先將待排序數組遞歸地拆分成兩個子數組,然后對每個子數組進行排序,最后將兩個有序子數組合并成一個有序數組。
- 在實現中,我們可以使用“分治法”來完成這個過程,即將大問題分解成小問題來解決。
歸并排序的算法復雜度為 O(nlogn),是一種比較高效的排序算法,因此在實際應用中被廣泛使用。
雖然歸并排序看起來比較復雜,但是只要理解了基本思路,實現起來并不困難,而且它還是一個非常有趣的算法。
二. 歸并排序的流程
歸并排序是一種基于分治思想的排序算法,其基本思路可以分為三個步驟:
步驟一:分解(Divide):歸并排序使用遞歸算法來實現分解過程,具體實現中可以分為以下幾個步驟:
- 如果待排序數組長度為1,認為這個數組已經有序,直接返回;
- 將待排序數組分成兩個長度相等的子數組,分別對這兩個子數組進行遞歸排序;
- 將兩個排好序的子數組合并成一個有序數組,返回這個有序數組。
步驟二:合并(Merge):合并過程中,需要比較每個子數組的元素并將它們有序地合并成一個新的數組:
- 可以使用兩個指針 i 和 j 分別指向兩個子數組的開頭,比較它們的元素大小,并將小的元素插入到新的有序數組中。
- 如果其中一個子數組已經遍歷完,就將另一個子數組的剩余部分直接插入到新的有序數組中。
- 最后返回這個有序數組。
步驟三:歸并排序的遞歸終止條件:
- 歸并排序使用遞歸算法來實現分解過程,當子數組的長度為1時,認為這個子數組已經有序,遞歸結束。
總體來看,歸并排序的基本思路是分治法,分成子問題分別解決,然后將子問題的解合并成整體的解。
三. 歸并排序的圖解
四. 歸并排序的代碼
下面是TypeScript實現的歸并排序代碼,帶有詳細的注釋:
// 定義函數mergeSort,參數是待排序數組arrfunction mergeSort(arr: number[]): number[] { // 計算數組長度 const n = arr.length; // 如果數組長度小于等于1,則直接返回該數組 if (n <= 1) {return arr; } // 計算中間位置 const middle = Math.floor(n / 2); // 對左邊的數組進行歸并排序 const left = mergeSort(arr.slice(0, middle)); // 對右邊的數組進行歸并排序 const right = mergeSort(arr.slice(middle)); // 合并兩個排好序的數組 return merge(left, right);}// 定義函數merge,參數是兩個排好序的數組left和rightfunction merge(left: number[], right: number[]): number[] { // 定義指針變量,分別指向兩個數組的開頭 let i = 0, j = 0; // 定義一個空數組,用來存放合并后的數組 const result = []; // 比較兩個數組的第一個元素,將較小的放入result數組 while (i < left.length && j < right.length) {if (left[i] < right[j]) { result.push(left[i++]);} else { result.push(right[j++]);} } // 將沒有比較完的剩余元素放入result數組 while (i < left.length) {result.push(left[i++]); } while (j < right.length) {result.push(right[j++]); } // 返回合并后的數組 return result;}// 測試數據const testArr = [5, 2, 9, 1, 5, 6];// 調用插入排序函數const sortedArr = mergeSort(testArr);// 打印結果console.log(sortedArr);
代碼執行的過程:
mergeSort
函數實現歸并排序的遞歸調用,在該函數內,如果數組的長度小于等于1,直接返回該數組。- 如果數組的長度大于1,那么執行以下代碼:
- 先計算數組的中點,并將數組分為左右兩半。
- 遞歸調用左邊和右邊的數組,最終得到兩個有序的數組。
merge
函數實現將兩個有序的數組合并為一個有序的數組。
五. 歸并排序的時間復雜度
復雜度的分析過程:
- 假設數組長度為 n,需要進行 logn 次歸并操作;
- 每次歸并操作需要 O(n) 的時間復雜度;
- 因此,歸并排序的時間復雜度為 O(nlogn)。
最好情況: O(log n)
- 最好情況下,待排序數組已經是有序的了,那么每個子數組都只需要合并一次,即只需要進行一次歸并操作。
- 因此,此時的時間復雜度是 O(log n)。
最壞情況: O(nlogn)
最壞情況下,待排序數組是逆序的,那么每個子數組都需要進行多次合并。
因此,此時的時間復雜度為 O(nlogn)。
平均情況: O(nlogn)
- 在平均情況下,我們假設待排序數組中任意兩個元素都是等概率出現的。
- 此時,可以證明歸并排序的時間復雜度為 O(nlogn)。
六. 歸并排序的總結
歸并排序是一種分治策略的排序算法,是利用分治的思想將一個大問題分成小問題,并在適當的地方合并它們以解決該問題的方法。
它是一種穩定的排序算法,時間復雜度為O(nlogn)。
歸并排序使用了額外的空間,因此更適合處理大數據。
- 歸并排序的基本流程是通過遞歸將數組分成兩半,分別進行遞歸排序,最終再進行合并。
- 具體來說,將數組的中間元素作為分界點,分別對左右兩邊的數組進行排序,并在排序完成后進行合并。
歸并排序的代碼實現較為簡單,但要注意關于遞歸函數和合并函數的實現。
歸并排序是一種不需要過多研究的算法,適合于所有的排序場景。
以上就是TypeScript實現十大排序算法之歸并排序示例詳解的詳細內容,更多關于TypeScript算法歸并排序的資料請關注其它相關文章!
