演算法 快速排序的實現

2021-09-24 22:16:50 字數 1485 閱讀 5131

理解:

快速排序對問題分而治之的一種方法,在每一趟排序後,都能確定乙個數的位置(即分割點),因此快速排序的核心是確定分割點的位置並把陣列按大小分在分割點的兩側。

因此快排可以分為兩部分,第一部分是遞迴處理問題,第二部分是找到分割點

第一部分:

def quicksort(l, r):

if l >=r:

return

p = partition(nums, l, r)

quicksort(l, p - 1)

quicksort(p + 1, r)

第一部分比較簡單, 關鍵在於第二部分的實現,在這裡我列出2種比較常見的方法

方案一

def partition(a, l, r):

tmp = a[r]

i = l - 1

for j in range(l, r):

if a[j] < tmp:

i += 1

a[i], a[j] = a[j], a[i]

a[i + 1], a[r] = a[r], a[i + 1]

return i + 1

這個數《演算法導論》傷的偽**實現,思路是以陣列最後乙個值作為分割點 x,使用兩個指標i和j,在遍歷j的過程中,每次把j停在比 x 小的位置,然後把 i + 1 和 j 的位置的值對調。

在這個過程中,i + 1 位置的值有兩種情況

1: 小於x,這種情況下,由於j會停在比x小的地方,那麼j = i + 1,所以此時對調 i + 1 和 j 的位置等於沒變。

2.大於等於x,這種情況下 j 會停在後面第乙個比 x 小的位置,此時對調相當於是把比 x 小的的值移到了陣列前面,比 x 大的值移到了陣列後面

通過這個演算法能保證當 j 遍歷完之後,在 0~i 位置的值都比 x 小,而在 i + 1 ~ n - 2 的值都比x大。這樣,在最後對調 i + 1 和 n - 1 位置(即x)的值就完成了分割,並且 i + 1就是分割點

方案二:

def partition(a, l, r):

tmp = a[l]

while l < r:

while a[r] > tmp and l < r:

r -= 1

a[l] = a[r]

while a[l] <= tmp and l < r:

l += 1

a[r] = a[l]

a[l] = tmp

return l

這個方法就是比較常見的通過一前一後兩個指標調換值的位置。值得注意的是,該方法使用的思路略微不同於直接swap,而是先找到右邊比 x 小的值,把左邊 i 位置直接設定成右邊的值(因為初始設定以第乙個數作為分割值,所以可以直接覆蓋掉這個值),然後再找到左邊比 x 大的值,把右邊 j 位置直接設定成左邊的值(此時右邊的值在上一步已經賦值到了左邊)當i = j 時,這個位置的值已經被左邊或者右邊賦值,並且這個點就是分割點。

快速排序演算法的實現

快速排序之所比較快,因為相比氣泡排序,每次排序的時候設定乙個基準點,將小於等於基準點的數全部放到基準點的左邊,將大於等於基準點的數全部放到基準點的右邊。這樣在每次交換的時候就不會像氣泡排序一樣每次只能在相鄰的數之間進行交換,交換的距離就大的多了。因此總的比較和交換次數就少了,速度自然就提高了。當然在...

快速排序演算法實現

快速排序演算法的原理 將數列中任取乙個數,將其左部放置比其小的數,其右部放置比其大的數。然後,對其左,右部遞迴執行這種分割過程。原始碼如下 int32 sorteddata int32 quicksort int32 sortdata,dword sortdatalen assert sortdat...

快速排序演算法實現

學完了快速排序演算法,感覺挺容易的,所以趁著有點時間就寫了個實現程式。採用了介面和實現分離的原則 qsort.h inte ce of the quick sort define num 2000 設定最多個數為1999個 class qsort qsort.cpp include qsort.h ...