1. 程式人生 > >用Python實現快速排序(Quicksort)演算法

用Python實現快速排序(Quicksort)演算法

1.快速排序(Quicksort)演算法介紹

快速排序(Quicksort)是對氣泡排序的一種改進,但是不是穩定的排序演算法

2.演算法思想

1)設定兩個變數i、j,排序開始的時候:i=0,j=N-1;
2)以第一個陣列元素作為關鍵資料,儲存在key中,即key=A[0];
3)從j開始向前搜尋,即由後開始向前搜尋(j--),找到第一個小於key的值A[j],用A[j]覆蓋A[0],
4)從i開始向後搜尋,即由前開始向後搜尋(i++),找到第一個大於key的A[i],用A[i]覆蓋A[j]  即每一次覆蓋上一次的
5)重複第3、4步,直到i=j;找到符合條件的值,進行交換的時候i, j指標位置不變。另外,i==j這一過程一定正好是i+或j-完成的時候,此時令迴圈結束。
6) 將K還原
7) 第一遍快速排序不會直接得到最終結果,只會把比k大和比k小的數分到k的兩邊。為了得到最後結果,需要再次對下標2兩邊的陣列分別執行此步驟,然後再分解陣列,直到陣列不能再分解為止(只有一個數據),才能得到正確結果。

3. 第一趟排序 舉例如下

key = 3
i-->                  <--j
3   7    6    2    4   5        j走

i-->         <--j
2   7    6    2    4   5        i走

    i-->     <--j
2   7    6    7   4   5       j走

    i--><--j     
2   3    6    7   4   5       i走

 第一趟排序走完,key(key = 3)左邊的值都比3小,key右邊的值都比key大

 4.用Python3實現

    方法1

def quick_sort(list, low, high):
    """
    控制快速排序遞迴的主函式
    :param list:使用者傳入的待排序列表
    :param low:列表左下標
    :param high:列表右下標
    """

    if low < high:
        k_index = deal_list(list, low, high)

        # 遞迴分界值左邊的一組
        quick_sort(list, low, k_index - 1)
        # 遞迴分界值右邊的一組
        quick_sort(list, k_index + 1, high)


def deal_list(list, low, high):
    """實現每趟排序,並找出分界值的下標k_index"""

    # 必須把low ,high儲存起來,上面的主函式的left right始終不變
    left = low
    right = high

    # 將列表最左邊的值賦值給k
    k = list[low]

    while left < right:  # 當左右"指標"未碰頭時就一直比較移動下去
        # 從右邊開始,如果比K大:right左移一位,繼續比較
        while list[right] > k:
            right -= 1

        # 從左邊開始,如果比K小: left右移一位,繼續比較
        while list[left] <= k:
            left += 1

        # 若移動完,二者仍未相遇則交換下標對應的值
        if left < right:
            list[right], list[left] = list[left], list[right]

    # 若移動完,已經相遇,則交換right對應的值和k
    list[low] = list[right]
    list[right] = k
    return right

if __name__ == '__main__':

    list = [6, 1, 2, 7, 9, 3, 4, 5, 10, 8]
    quick_sort(list, 0, len(list) - 1)
    print(list)

方法2

import time, random


def quick_sort(list, low, high):
    # 1)
    # 必須將low  high儲存,因為下面的遞迴 還要固定著 最邊界
    i = low
    j = high
    if i >= j:
        return list

    key = list[i]  # 2)
    while i < j:
        # 3)
        while i < j and list[j] >= key:
            j = j - 1
        list[i] = list[j]

        # 4)
        while i < j and list[i] <= key:
            i = i + 1
        list[j] = list[i]

    # 6)
    list[i] = key

    # 7)
    quick_sort(list, low, i - 1)
    quick_sort(list, j + 1, high)
    return list


if __name__ == '__main__':
    list = [random.randint(1, 100) for i in range(100)]
    start_time = time.time()
    quick_sort(list, 0, len(list) - 1)
    # list = sorted(list)
    end_time = time.time()
    print("所用時間:", end_time - start_time)

5.結果如下

7.時間複雜度 空間複雜度分析

在最優的情況下,快速排序演算法的時間複雜度為O(nlogn)。
平均的情況 O(nlogn)。

就空間複雜度來說,主要是遞迴造成的棧空間的使用,最好情況,遞迴樹的深度為log2n,其空間複雜度也就為O(logn),最壞情況,需要進行n‐1遞迴呼叫,其空間複雜度為O(n),平均情況,空間複雜度也為O(logn)。

如果你和我有共同愛好,我們可以加個好友一起交流!