MergeSort與QuickSort的詳細分析

2021-08-10 11:15:54 字數 1269 閱讀 2958

mergesort和quicksort是兩種比較類似的sort方式,他們都是通過divide and conquer來實現的。都需要使用recursion的方式進行排序。

歸併排序和快排是兩種比較類似的排序方式, 他們都是通過分割占領來實現, 都需要使用遞迴進行排序

切片,將n個元素分成兩部分進行排序,每個子部分也會再繼續分成兩部分排序,直到只有2個元素進行比較排序。這就用到遞迴。

把排序好的每個元素再合併起來組成有序列表,這個就是合併( merge ),或者說是占領( conquer )。這兩種sort都需要合併這一步驟,但是細節不同。

- 歸併排序:

切片比較簡單,將所有元素以二分法方式分割,就是說分開後左邊與右邊元素的個數是相等的,或者相差 1(比如5個,分成左3、右2)。分割過程的複雜度只需計算為1就可以了。

合併部分相對複雜。當所有元素被分為很多個小部分進行排序後,每個小部分裡面的元素都是排好順序的,然後需要和另乙個小部分裡的元素排序。因為在切片的時候是以二分法方式分開的,左邊和右邊的元素沒有任何大小關係,所以在合併的過程中需要將左邊部分的元素與右邊部分的元素逐一比較然後儲存在乙個新的 list 裡面。這樣,合併過程的複雜度為n。

合併排序的複雜度為 n+2t(n/2) (這裡的第乙個n是指合併的複雜度)。最終複雜度為nlgn.

- 快排

切片複雜,而且有多種方法,

方法一:使用第乙個元素做為比較標準值,然後把比這個標準值小的所有元素放左邊,大的放在右邊,這樣得到的兩個部分左邊任意元素都比右邊任意元素小。

方法二:使用中間值作為比較標準值。我們選擇標準值的標準是盡量選擇不大不小接近中間的元素,這樣根據這個標準值所分開的兩部分的數量不會相差太大。

如果使用方法一,而 list 中的元素剛好又是已排好序的,那劃分的兩部分數量懸殊,演算法複雜度非常高,為n*n。

一般情況,快排的切片的複雜度為n. 假設快排的切片方法分開後的所有小部分為 a, b, c… 那麼 a 中的所有元素都比 b 中的小,b 中的所有元素比 c 中的小。這樣在合併的時候非常簡單,只要把 a, b, c…裡的元素排好順序,然後把 b 直接放在 a 後面就好了。這裡的複雜度只有1。所以整個快排的複雜度為 n+2t(n/2) 這裡的第乙個n指切片的複雜度。最終複雜度為nlgn.

總體來說,快排的切片複雜合併簡單,歸併排序的切片簡單合併複雜。了解原理後就可以根據不同情況選擇不同的排序方法。

**:

mergesort與逆序對個數

mergesort 如下 def merge lists left,right res lc rc 0 while lc len left and rc len right if left lc right rc lc 1 else rc 1 res.extend left lc res.exten...

原 quick整合spine動畫

更新說明 新增了骨骼繫結node用法 參考 在skeletonrenderer.h 和cpp裡面新加了以上鏈結的內容,在skeletonrenderer luabinding.tolua需要新添ccnode skeletonrenderer getnodeforslot const char slo...

演算法設計與分析 上機題Mergesort

include using namespace std define n 100 int g array n 存放輸入的數字 static int count 存放元素的個數 初始化函式 void initial 合併函式 void merge int a,int l,int m,int r els...