上篇博客咱們主要聊了堆排序的相關內容,本篇博客,咱們就來聊一下歸併排序的相關內容。歸併排序主要用了分治法的思想,在歸併排序中,將咱們須要排序的數組進行拆分,將其拆分的足夠小。當拆分的數組中只有一個元素時,則這個拆分的數組是有序的。而後咱們將這些有序的數組進行兩兩合併,在合併過程當中進行比較,合併生成的新的數組仍然是有序的。而後再次將合併的有序數組進行合併,重複這個過程,知道整個數組是有序的。git
下方咱們先給出兩個有序數組合並的示意圖以及代碼,而後給出歸併排序的相關內容。歸併排序其實就是拆分+合併。廢話少說,開始今天的內容。github
1、合併兩個有序數組數組
在本篇博客的第一部分咱們先給出合併兩個有序數組的示意圖以及相關代碼,在歸併排序時,咱們會使用到此部分的內容。下方會給出兩個有數數組的合併,而且會給出相應的代碼實現。數據結構
1.有序數組合並的示意圖函數
由於兩個有序數組在合併後的新的數組仍然是有序的,因此咱們須要對有序數組中的元素進行比較。每次從兩個數組中取出最小的那個元素,而後將兩個元素進行比較,將最小的那個元素放入到新的數組中。下方就是有序數組合並的示意圖。測試
首先從兩個有序數組中取出最小的值,以下所示。咱們將9和10取出後進行比較,將較小的9存入咱們新的數組中。
重複上個步驟,若是有一個數組中的元素被取完,將另外一個數組中剩餘的元素直接追加到咱們的新的數組中便可。
2.代碼實現spa
根據上述示意圖給出相關的代碼實現並不困難,下方就是上述過程的代碼實現。下方這個mergeArray()函數,就是將兩個有序數組合併成一個新的有序數組的具體代碼實現。mergeArray()的兩個參數就是即將合併的兩個有序數組,而返回值就是合併後新的有序的數組。代碼比較簡單,在此就不作過多贅述了。blog
2、歸併排序排序
上述實現完兩個有序數組合併成新的有序數組完畢後,接下來就該歸併排序出場了。在歸併排序過程當中,會使用到上述的內容。由於咱們將無序數列進行分割後,就會不斷調用上述的合併代碼,將小的有序的數組合併成較大的有序數組,再次合併,直到咱們原始的數組是有序的爲止。下方會給出相應的示意圖以及歸併排序的Swift代碼實現。教程
1.歸併排序示意圖
下方就是咱們歸併排序的示意圖,稍後的代碼實現也是根據下方的示意圖來寫的。因此對下方示意圖的充分理解仍是頗有必要的。在下方示意圖中,從上往下就是咱們歸併排序的整個過程。咱們須要排序的序列爲[62, 88, 58, 47, 62, 35, 73, 51, 99, 37, 93]。下方是對每一步的解析:
下方就是拆分+屢次合併的詳細過程,最終咱們獲得的就是一個有序序列。以下所示:
二、上述過程的代碼實現
根據上述的示意圖,咱們給出相應的代碼實現應該是比較容易的。就是將咱們的無序數組進行拆分,而後進行屢次合併,最後合併成一個大的有序數組。下方代碼就是對上述過程的描述。
而tempArray最終的數組就是歸併排序的最終結果。下方是整個過程,代碼並不複雜。
上述代碼的實如今有些數據結構的教程上是使用遞歸實現的,即便是不使用遞歸實現也比上述代碼要麻煩。
3、測試用例
對上述代碼的測試咱們仍然會使用到咱們以前的測試用例,由於上述排序類仍然遵循咱們以前定義的SortType協議。下方就是本篇博客的測試用例,也是全部排序方式的測試用例。這個MergeSort類就是咱們歸併排序的類。
上述用例的輸出結果以下,從輸出結果中,咱們就能明顯的看出拆分和合並的整個過程。以下所示:
本篇博客對堆排序的介紹就先到這兒,下篇博客咱們將會介紹「快速排序」的詳細內容。本篇博客的相關代碼依然會在github上進行分享,下方是github分享地址,以下所示:
github代碼分享地址:https://github.com/lizelu/DataStruct-Swift/tree/master/AllKindsOfSort