當前位置: 妍妍網 > 辦公

一看就懂的簡版快速排序程式碼

2024-02-19辦公

大家好,歡迎來到 Crossin的編程教室 !

如果你還不懂快速排序,那麽希望這篇講解可以讓你理解快排的核心思想。

上次介紹了程式碼視覺化工具pythontutor,並且用快排的程式碼做了演示。

後來有小夥伴說沒太看懂。那今天我們就用pythontutor來詳細過一遍這個快排的程式碼。

快速排序是一種非常常見的排序演算法,雖然在實際開發中,你幾乎不需要自己去寫,但它卻是筆試面試的高頻問題,甚至「手寫快排」已經成為了一個梗。

快排的原理說起來很簡單,就是從序列中挑出一個基準的數,比它小的放左邊,比它大或相等的放右邊。然後對兩邊的序列再分別采用這個方式進一步劃分,直到子序列只剩下一個或沒有元素為止。

這種思想叫作 分治 ,就是把一個復雜的問題劃分成相同或相似子問題,以此類推,直到子問題可以簡單求解。分治在程式碼上的實作通常會用到 遞迴函式

來看具體的程式碼:

def quick_sort(arr): if len(arr) <= 1: return arr pivot = arr[0] left = [] right = [] for i in arr[1:]: if i < pivot: left.append(i)else:right.append(i)return quick_sort(left) + [pivot] + quick_sort(right)arr = [3, 2, 7, 9, 5, 1, 8] sorted_arr = quick_sort(arr) print(sorted_arr)

quick_sort就是實作快排的遞迴函式,arr是待排序的列表

遞迴函式都需要有一個結束條件,不然程式就要死迴圈到StackOverflow了,這裏的 結束條件就是序列的長度小於等於1 ,因為沒有元素或只有1個元素的序列不用做任何操作它就是有序的。

當然一開始,我們這個序列是不滿足的,於是程式往下走,選取列表第一個元素3為pivot,也就是基準數,然後建立左右兩個子列表。接下來就是對第一個元素往後的列表進行遍歷,比基準小的(2、1)就加到左列表,相等或大的(7、9、5、8)就加到右列表。

到這裏都還比較好理解,然後接下來就是整個程式碼最核心的一句話了。

return quick_sort(left) + [pivot] + quick_sort(right)

這裏直接就return返回結果了,結果是什麽呢,是把左列表進行快排的結果,加上基準數,再加上右列表進行快排的結果。

看起來好像還挺簡單的,可是現在左列表和右列表都還沒有排序呢,怎麽就能這樣加起來呢?

哎,這就是遞迴的精妙之處。我們繼續結合程式碼往下走。

單看這行程式碼的優先級,會先去呼叫quick_sort(left)拿到返回值,再呼叫quick_sort(right)拿到返回值,然後再執行列表的+運算,也就是合並列表,最後return返回。

那現在再次進入 quick_sort,參數就成了 left,也就 [2, 1]。雖然這時候人眼一看就知道排序結果應該是 [1, 2],但程式還是要一步一步來。pivot是2,left 是 [1],right是空列表。然後繼續下一層的遞迴。這時候,quick_sort([1]) 和 quick_sort([]) 都會觸發結束條件了,於是直接返回,返回結果再和剛才這一層的pivot,也就是 [2] 合並在一起,就成了 [1, 2]。然後,它才能返回給再上面一層的函式,也就是我們最外層的quick_sort裏面這個quick_sort(left)的結果。

解決了quick_sort(left),接下來就是quick_sort(right)了,這時參數成了[7,9,5,8],pivot是7,left是[5],right是[9,8]。

left因為只有一個元素所以呼叫後直接返回,但right還要繼續往下走,pivot是9,left是[8],right是[],再多呼叫一層,然後返回[8,9],再跟上一層合並成[5,7,8,9],返回給最外層。

這時候遞迴呼叫的函式全部都返回了,left、pivot、right再加一起,就是最後的結果[1,2,3,5,7,8,9],返回並輸出,程式結束。

快速排序還有其他一些寫法,比如不新建子列表,而是在原列表上透過交換元素位置達到劃分左右子列表的目的,又比如使用列表裏前中後三個元素的中值作為劃分的基準數。這些會在一定程度上最佳化程式的執行效率,但核心的演算法原理還是一樣的。

作者:Crossin的編程教室

Crossin的新書【 碼上行動:用ChatGPT學會Python編程 】已經上市了。 本書以ChatGPT為輔助,系統全面地講解了如何掌握Python編程,適合Python零基礎入門的讀者學習。

購買後可加入讀者交流群,Crossin為你開啟陪讀模式,解答你在閱讀本書時的一切疑問。

添加微信 crossin123 ,加入編程教室共同學習 ~

感謝 轉發 點贊 的各位~