步驟
- 選取基準:從數據中選擇一個數作爲基準值(pivot),一般選擇最左邊。
- 分區操作:將數據中小於基準的全部放在pivot的左邊位置,其餘放在右邊位置。該(分區)操作完成之後,原來的基準會在數據的中間某一位置。
- 遞歸下去,得到有序結果。
圖解
詳情
List = [5, 1, 3, 2, 4],s = 0, t = 4
- 基準值tmp = 5,i=s,j=t
- j從右向左移動,即j=4,List[j]<=tmp,應該將4放前面5的位置,此時
- List = [4, 1, 3, 2, 4]
- i = 0,j = 4
- j位置的值只要發生了交換,就要改變比較的方向去,即從i開始去比較。
- i從左向右移動,即i=0,List[i]<=tmp,繼續向右移動i,此時,
- i = 1,j = 4
- 只要i處的值比tmp小,i就一直向右移,最後i移動到j的位置,即i = j = 4。只要i與j相遇,即i==j,就將tmp插入這個相遇的位置。
- 一輪操作下來,List = [1, 3, 2, 4, 5]。分別對基準左右兩個分區實時上述步驟,直至分區沒有元素未知。
- List = [1, 3, 2, 4, 5],tmp=5左側分區=[1, 3, 2, 4],右側爲空。
- 對分區[1, 3, 2, 4]採用上述步驟,得到tmp=1,數據爲[1, 3, 2, 4]。整個List=[1, 3, 2, 4, 5]
- 繼續對[3, 2, 4]採用上述步驟,得到tmp=3,數據爲[2, 3, 4]。整個List=[1, 2, 3, 4, 5]
複雜度
- 最好的情況,每次劃分都將數據分成左右兩個數量差不多的分區。這樣遞歸樹高度爲,每一層劃分的時間爲。
- 時間複雜度:
- 空間複雜度:
- 最壞的情況,每次劃分都將數據分成一個分區。這樣遞歸樹的高度爲,需要次劃分。
- 時間複雜度:
- 空間複雜度:
- 平均情況下,接近最好。
- 時間複雜度:
- 空間複雜度:
算法
# 一趟排序,目的是將左邊的一個元素作爲基準,將數據中小於基準全放基準的左邊,
# 大於的部分放基準的右邊,輸出基準最終位置
## s爲要排序的起始位置,t爲要排序的結束位置
def partition(List, s, t):
i, j = s, t
tmp = List[i] # 基準
while i<j:
while j>i and List[j]>=tmp: # 從右向左掃描,直到右邊的數比基準值小爲止
j -= 1 ## 向左移動
List[i] = List[j] ## 將右邊小於基準值的值排到前面i的位置去
while i<j and List[i]<=tmp: # 從左向右掃描,直到左邊的數比基準值大爲止
i += 1
List[j] = List[i]
List[i] = tmp
return i
def QuickSort(List, s, t):
# 遞歸部分
if s>=t:
return List
else:
i = partition(List, s, t)
QuickSort(List, s, i-1)
QuickSort(List, i+1, t)
return List