排序算法之快速排序及其優化

快速排序


其餘排序方法:選擇排序冒泡排序歸併排序快速排序插入排序希爾排序html


思想

從數組中選取一個元素,以它做爲比較基準,比它小的都放到數組左邊;比它大的則放到右邊。而後左邊的數組和右邊的數組也進行一樣的操做。這樣遞歸下去,最後數組就會成爲一個有序的數組。python

圖解

借用一下百科的圖:
數組

性能

快速排序時不穩定的,它的最好和平均時間複雜度爲O(nlogn)。
最壞的狀況就是每次所選的基準都是當前序列中的最大或最小元素,這樣每次劃分的兩個子數組中都有一個是空數組,則最終須要通過n次劃分,最壞的時間複雜度爲O(logn^2)。
python的遞歸層數是有限制的,當n大到必定程度時,就會崩掉。因此咱們應該儘可能避免最壞的狀況發生。性能

代碼

Python:優化

# 快速排序
# left爲第一個下標,right爲最後一個下標
def quickSort(arr, left, right):
    if left >= right: return

    # 將第一位元素設爲比較基準
    key = arr[left]

    i, j = left, right
    # 比基準小的元素都放到左邊,大的都放到右邊
    while i < j:
        while i < j and arr[j] >= key:
            j -= 1
        arr[i] = arr[j]

        while i < j and arr[i] <= key:
            i += 1
        arr[j] = arr[i]
    arr[i] = key

    # 左右兩邊的數組進行一樣的操做
    quickSort(arr, left, i - 1)
    quickSort(arr, i + 1, right)

優化

快速排序的優化主要針對於最壞狀況的優化,如何避免每次所選的基準都是當前序列中的最大或最小元素?
咱們一般是取第一位元素做爲基準值。數組若是一開始就是有序的話,就是最壞狀況了。
改進方法:
有一種方法就是在排序以前shuffle一下(打亂順序);
還有一種是不取第一位元素,而是取第一位、最後一位和中間位中的中值元素做爲基準值,這樣就能徹底避免最壞狀況了。ui

# 取中值
def midVal(arr, left, right):
    mid = left + right >> 1

    if arr[mid] > arr[right]:
        arr[mid], arr[right] = arr[right], arr[mid]
    if arr[left] > arr[right]:
        arr[left], arr[right] = arr[right], arr[left]
    if arr[mid] > arr[left]:
        arr[left], arr[mid] = arr[mid], arr[left]
    return arr[left]


# 快速排序
# left爲第一個下標,right爲最後一個下標
def quickSort(arr, left, right):
    if left >= right: return

    # 取第一位、最後一位和中間位中的中值元素做爲基準值
    key = midVal(arr, left, right)

    i, j = left, right
    # 比基準小的元素都放到左邊,大的都放到右邊
    while i < j:
        while i < j and arr[j] >= key:
            j -= 1
        arr[i] = arr[j]

        while i < j and arr[i] <= key:
            i += 1
        arr[j] = arr[i]
    arr[i] = key

    # 左右兩邊的數組進行一樣的操做
    quickSort(arr, left, i - 1)
    quickSort(arr, i + 1, right)

其餘排序方法:選擇排序冒泡排序歸併排序快速排序插入排序希爾排序code

相關文章
相關標籤/搜索