交排之快速排序算法

步驟

  • 選取基準:從數據中選擇一個數作爲基準值(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]

複雜度

  • 最好的情況,每次劃分都將數據分成左右兩個數量差不多的分區。這樣遞歸樹高度爲O(log2n)O(log_{2}n),每一層劃分的時間爲O(n)O(n)
    • 時間複雜度:O(nlog2n)O(nlog_{2}n)
    • 空間複雜度:O(log2n)O(log_{2}n)
  • 最壞的情況,每次劃分都將數據分成一個分區。這樣遞歸樹的高度爲nn,需要n1n-1次劃分。
    • 時間複雜度:O(n2)O(n^2)
    • 空間複雜度:O(n)O(n)
  • 平均情況下,接近最好。
    • 時間複雜度:O(nlog2n)O(nlog_{2}n)
    • 空間複雜度:O(log2n)O(log_{2}n)

算法

# 一趟排序,目的是將左邊的一個元素作爲基準,將數據中小於基準全放基準的左邊,
# 大於的部分放基準的右邊,輸出基準最終位置
## 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章