快排及優化

思路:

快速排序的本質就是選取一個基準數,通過一次快排把基準數大的都放在基準數的左邊,把比基準數小的放在基準數的右邊,這樣就找到了基準數在數組中的正確位置。
然後可以用遞歸的方式分別對前半部分和後半部分排序,最終實現整體數組有序。

快排是不是穩定排序?

所謂排序的穩定性,就是指在排序過程中,在對某關鍵字排序後會不會改變其他關鍵字的順序。快排會改變,所以不是穩定排序。

代碼:

常規代碼1:

def AdjustPartition(list1,low,high):
    if low < high:
        left = low
        right = high
        key = list1[left]
        while left < right:
            while left < right and list1[right] >= key:
                right = right - 1
            list1[left] = list1[right]
            while left < right and list1[left] <= key:
                left = left + 1
            list1[right] = list1[left]
        list1[left] = key
        AdjustPartition(list1,low,left-1)
        AdjustPartition(list1,left+1,high)
    return list1

常規代碼2:

def quick_sort(arr):
    if len(arr) < 2:
        return arr
    key = arr[0]  # 以第一個關鍵字作爲基準數
    left, right = [], []
    arr.remove(key)
    for item in arr:
        if item >= key:
            right.append(item)
        else:
            left.append(item)
    return quick_sort(left) + [key] + quick_sort(right)

python一行代碼實現快排:

def quick_sort(a):
    if len(a) > 1:
        return quick_sort([i for i in a[1:] if i <= a[0]]) + [a[0]] + quick_sort([i for i in a[1:] if i > a[0]])
    else:
        return a

轉化爲一行:

quick_sort = lambda a:a if len(a) <= 1 else quick_sort([i for i in a[1:] if i <= a[0]]) + \
[a[0]] + quick_sort([i for i in a[1:] if i > a[0]])

快排優化

如果數組元素是隨機的,那麼程序的運行時間不會有太大的波動。如果數組元素已經基本有序時,此時的固定基準劃分就容易產生最壞的情況,即快速排序變成冒泡排序,時間複雜度爲O(n2n^{2})。
eg: 序列1 2 3 6 12 18,如果用固定基準進行快排:(【】內爲基準數)
第一趟:【1 】2 3 6 12 18
第二趟:1【 2】 3 6 12 18
第三趟:1 2 【3】 6 12 18
第四趟:1 2 3 【6】 12 18
第四趟:1 2 3 6 【12】 18

快排基準的選擇:

(1)固定基準
比如每次以第一個關鍵字作爲基準數。可能會退化爲冒泡排序。
(2)隨機基準
可以利用隨機函數隨機生成在[low,high]範圍內的數作爲基準數的下標。
(3)三數取中
隨機基準選取的隨機性,因此即使是同一個數組每次效率也是不一樣的,此時可以選擇三數取中的方法選取基準數。它的思路是:選取數組開頭,中間和結尾的元素去比較,選擇中間的值作爲快排的基準。這種方式既能解決待排數組基本有序的情況,而且選取的基準也不是隨機的。

eg:序列1 2 3 6 12 18,30,如果用三數取中進行快排:
    因爲:
    數組開頭是1,中間是6,結尾是30
    所以:
    所以基準數選擇6進行快排。

快排優化方案

  1. 在數組長度大於某一個閾值範圍時,使用遞歸快排,當數據長度小於閾值時,使用插入排序。因爲處理較短序列時插入排序效果更好。
  2. 在partition中選取基準數時,選取三路取中。
  3. 進行三路快排優化。即將數組劃分爲左邊小於基準數,中間等於基準數,右邊大於基準數,這樣兩端遞歸時可以縮小遞歸數組的大小。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章