1. 程式人生 > >資料結構之內部排序--快速排序

資料結構之內部排序--快速排序

概要

-IDE:Pycharm
-Python版本:python3.x
-演算法分類:內部排序->交換類排序->快速排序

演算法思想

待排序記錄序列中選取一個記錄為樞軸,其關鍵字為$k_1$,然後將其餘關鍵字小於$k_1$的移到前面,大於$k_1$的移到後面,結果是待排序記錄分為兩個子表,最後將關鍵字$k_1$插到中間處。這個過程稱為一趟快速排序。對分割後的序列,按上述規則繼續劃分直到所有子表長度不大於$1$,此時待排序記錄成為一個有序表。

演算法分析

分析快速排序的時間耗費,共需要進行多少趟排序,取決於遞迴深度。
1.快速排序的最好情況是每一趟排序都將序列一分為二,正好在表中間,將表分為大小相等的子表,類似於折半查詢,其時間複雜度約為$O(nlog_{2^n})$
2.快速排序的最壞情況是已經排好序,第一趟經過$n-1$次比較,第一個記錄停在原地,產生的左邊的列表長度為$0$,右邊的列表長度為$n-1$,這樣下來比較的次數為$\sum_{i=1}^{n-1}(n-i)=(n-1)+(n-2)+...+1=\frac{n(n-1)}{2}\approx \frac{n^2}{2}$
快速排序所需的時間平均值為$T_{avg}(n)=Knlog_{2^n}$,其中K為某個常數。
3.快速排序遞迴演算法的執行過程對應一顆而叉樹,理想狀態下是一顆完全二叉樹,遞迴工作站的大小,與此二叉樹的深度對應,平均情況下空間複雜度為$O(log_{2^n})$。

穩定性與時間複雜度

排序演算法 穩定性 時間複雜度 最好情況 最壞情況 空間複雜度
快速排序 不穩定 $O(nlog_{2^n})$ $O(nlog_{2^n})$ $O(n^2)$ $O(log_{2^n})$

Python程式碼清單

# !/usr/bin/python3
# _*_ coding:utf-8 _*_
# 快速排序

import sys, random, time  # 匯入包


def make_numbers(number, maxNumber):  # 用於生成列表的演算法。
    listA = []
    for i in range(number):
        listA.append(random.randint(0, maxNumber))
    print(listA)
    return listA  # 返回列表


def quick_sort(listA, low, high):  # 進行快速排序的演算法。
    global pos  # 設定全域性變數,因為我這裡是把一次排序的演算法寫到另一個方法裡的。
    if low < high:  # 判斷是否相交。
        pos = quick_pass(listA, low, high)  # 一次排序。
        quick_sort(listA, low, pos-1)  # 左子樹。遞迴呼叫。
        quick_sort(listA, pos+1, high)  # 右子數。
    return listA  # 返回排好的list


def quick_pass(listA, low, high):  # 一次快速排序演算法。
    pivot = listA[low]  # 記錄低點的值

    while low < high:  # 判斷是否相交
        while low < high and listA[high] >= pivot:  # 在沒有相交的情況下,從右向左尋找大於低點的值的數。
            high = high-1  # 高位減一。向前走一位。
        if low < high:  # 如果高低位沒有相交,
            listA[low] = listA[high]  # 沒啥意思。就是給個值。
            low = low + 1  # 低位向前1位。
        while low < high and listA[low] < pivot:  # 同理,尋找小於低點的值。
            low = low + 1
        if low < high:
            listA[high] = listA[low]
            high = high - 1
    listA[low] = pivot  # 最後,將低點的值放到low點,或者high點。(此地low = high)
    return low


if __name__ == '__main__':

    helpInfo = '''
        This program is for Quick Sort.
        How to use it! Follow the example!

        python Quick_Sort.py 10 100

        The 10 representative will generate ten numbers.
        100 representative the max-number you make.
        
    '''
    command = sys.argv[0:]  # 從鍵盤獲取輸入。
    if len(command) != 3 or 'help' in command:  # 對輸入的引數進行檢查。
        print(helpInfo)  # 列印幫助文字
    else:
        try:  # 嘗試將輸入測引數轉化為int型。
            number = int(command[1])
            maxNumber = int(command[2])
        except ValueError:  # 轉化失敗,出現ValueError
            print(helpInfo)  # 列印幫助文字。
            sys.exit(1)  # 異常退出
        listA = make_numbers(number, maxNumber)   # 一切正常, 生成列表listA。

    timeStart = time.time()  # 記錄開始時間
    list = quick_sort(listA, 0, number-1)  # 接收返回的排序好的list
    timeEnd = time.time()  # 記錄結束時間。
    timeIs = timeEnd - timeStart  # 記錄消耗時間。
    print('排序%d個數花費的時間是%f' % (number, timeIs))  # 輸出訊息資訊。
    print(list)

有什麼問題請聯絡我

QQ:3116316431 (請附上資訊)
E-mail:[email protected]