數據結構與算法小結——排序(七)
4. 歸並排序
4.1 遞歸實現
函數的遞歸本質上是一個壓棧出棧的過程,更廣意義上來說,函數調用都是壓棧和出棧的過程,排序這一系列完了 ,我打算寫一下函數調用和棧的關系的一章,看看能不能把這個過程理解透徹一些。
具體來說歸並排序的遞歸實現。其主要思想是把待排序序列分為大小基本相同的兩個部分,分別對前後兩個部分進行同樣的操作,調用自身不斷壓棧。到最後一層只有一個元素後,棧空間彈出棧頂元素,按照原先的切割部位,進行merge操作,見圖 1。
merge操作是用i、j兩個變量來循環前一段元素和後一段元素,一個一個比較,小的就依次放在新排好的序列中,i(或j)+1,繼續往後比。最後剩余的元素一次性接在已排好序的元素後面即可,圖示見圖 2。非遞歸的merge比較簡單,按照壓棧時的切割部位合並即可,不會出現還有剩余的段沒有辦法merge的問題,非遞歸則會出現這種問題,詳細可以見下一節。
前面在說快速排序的時候提到,快速排序用了遞歸,歸並排序也用了遞歸,兩者的區別是什麽?區別在於快速排序做的是遞歸的前處理,即用pivotvalue讓前小後大;遞歸的歸並排序做的是遞歸的後處理,將切割後的元素用merge操作合並。
圖 1 遞歸的歸並排序
圖 2 merge操作(遞歸的後處理操作)
分析遞歸的歸並排序的時間復雜度,畫出遞歸樹可以發現,遞歸樹是完全二叉樹,所以其時間復雜度最好、最壞、平均都是O(nlgn)。
分析遞歸的歸並排序的空間復雜度,由於用到了遞歸棧,所以會用到額外的O(lgn)的空間;另外,在排序時還會用到額外的O(n),所以其空間復雜度為O(n+lgn)。
歸並排序還有一個優點是它是穩定的。
總結其時間、空間復雜度、穩定性和適用場合如圖 3。
圖 3 遞歸的歸並排序相關
數據結構與算法小結——排序(七)