1. 程式人生 > >python常用排序演算法

python常用排序演算法

一 氣泡排序

遍歷列表,比較相鄰的兩個元素的大小,如果第一個數小於第二個數繼續移動,否則交換兩個元素的位置 。
時間複雜度:平均:O(n²),最好:O(n),最壞:O(n2),穩定性:穩定。
這裡寫圖片描述

# coding=utf-8
def bubbling(li):
    length = len(li)
    # 控制迴圈的總次數
    for j in range(0,length-1):
        # 控制每次迴圈時比較位置元素的
        for i in range(0,length-j-1):
            if li[i] > li[i+1]:
                li[i],li[i+1
] = li[i+1],li[i] return li if __name__ == "__main__": lists = [54, 26, 93, 77,17, 77, 31, 44, 55, 20] l = bubbling(lists) print l

效果圖
這裡寫圖片描述

二 插入排序

從無需列表中依次選出與有序列表作比較。
時間複雜度O(n^2),最優時間複雜度O(n),穩定性:穩定。
這裡寫圖片描述

# coding=utf-8

# 插入排序,假設第一個元素為有序列表,第二個到最後的元素為無需列表
# 從無序列表中依次取出元素和有序列表進行比較,如果小於就交換位置
def insert_sort(li): # 獲取長度 length = len(li) # 從第二個元素開始遍歷控制比較總次數 for j in range(1,length): # 取出的元素和前面的元素依次比較如果小於就交換位置 for i in range(j,0,-1): if li[i]<li[i-1]: li[i],li[i-1] = li[i-1],li[i] else: break return
li if __name__ == "__main__": lists = [17, 20, 999,31, 44, 54, 55, 77, 93, 226] L=insert_sort(lists) print L

效果圖
這裡寫圖片描述

三 選擇排序

假設一個元素為最小值,用其他的元素依次和它進行比較,如果不是最小就交換位置。
時間複雜度:平均,最好,最壞都為O(n²),穩定性:不穩定
這裡寫圖片描述

#coding=utf-8

def selection(li):
    # 獲取長度
    length = len(li)
    # 控制迴圈的總次數,假設下角標為j的元素為最小值
    for j in range(0,length):
        mix_index = j
        # 從下一個元素開始遍歷,依次和下角標為j的元素比較
        # 如果比假設最小值的元素小則記錄這個下角標
        for i in range(j+1,length):

            if li[i]<li[mix_index]:
                mix_index = i
        # 比較更新之後的下角標是否與假設的下角標一致
        # 如果不一致交換這兩個元素的位置
        if mix_index != j:
            li[mix_index],li[j] = li[j],li[mix_index]
    return li


if __name__ == '__main__':
    lists = [54, 226, 93, 17, 77, 31, 44, 55, 20]
    l=selection(lists)
    print l

效果圖
這裡寫圖片描述
紅色表示當前最小值, 黃色表示已排序序列,藍色表示當前位置

四 快速排序

原理:通過一次排序將資料分割為兩部分,其中一部分的所有值都比另一部分小,通過遞迴的方式將資料變為有序數列
時間複雜度:平均O(n log n) ,最好O(n log n) ,最壞O(n²),穩定性:不穩定。
方法:
1.在數列中挑出一個元素作為中間值,
2.重新排序數列,將比中間值小的放到前面,比中間值大的放到基準後面
3.遞迴,將兩個獨立的部分非別排序

這裡寫圖片描述

#coding=utf-8
# 快速排序選擇一箇中間值,比中間值小的放到左邊,否則放到右邊
def quick_sort(li,start,end):
    '''

    :param li 列表:
    :param start 列表的起始位置:
    :param end 列表的結束位置:
    :return 排序後的列表:
    '''
    # 遞迴結束條件
    if start>=end:
        return li
    # 假設中間值為start位置上的值
    mid_value = li[start]
    # 左側遊標的起始位置和右側遊標的起始位置
    left_cur = start
    right_cur = end
    # 滿足左側遊標<右側遊標的位置,就執行迴圈
    while left_cur <right_cur:
        # 右側遊標的值大於中間值,並且左右遊標沒有重合就移動右側遊標
        # 否則賦值給左側遊標
        while left_cur < right_cur and li[right_cur]>=mid_value:
            right_cur-=1
        li[left_cur] = li[right_cur]

        while left_cur < right_cur and li[left_cur]<mid_value:
            left_cur+=1
        li[right_cur] = li[left_cur]

    # 將假設的中間值放到兩個遊標指向的位置(中間位置)
    li[right_cur] = mid_value
    # 遞給快速排序中間值左側的序列
    quick_sort(li,0,right_cur-1)
    # 遞迴快速排序中間值右側的序列
    quick_sort(li,right_cur+1,end)
    return li


if __name__ == '__main__':
    lists = [17, 20, 1,999, 31, 44, 54, 55, 77, 93, 226]
    l=quick_sort(lists,0,len(lists)-1)
    print l

效果圖
這裡寫圖片描述

五 希爾排序

將無需列表按照一定的步長分割為多個子序列,分別對子序列進行插入排序,之後在縮短步長,重複之前的操作,直到最後步長為1。
時間複雜度:平均:O(nlogn)~O(n2),最好:O(n1.3次方),最壞:O(n²),穩定性:不穩定
方法:
1. 指定一個步長,一般是列表長度的一半
2. 按照步長將每一個子序列進行插入排序
3. 再次縮短步長重複操作,直到最後的步長是1,進行最後一次插入排序。
這裡寫圖片描述

# coding=utf-8

def shell_sort(li):
    # 取出列表的長度
    length = len(li)
    # 設定初始步長
    gap = length // 2
    # 控制迴圈次數,步長>=1
    while gap >= 1:
        # 使用插入排序,比較相鄰的兩個元素之間相差一個步長
        # 判斷與前一個元素的大小,如果小於繼續移動,否則交換位置
        for i in range(gap,length):
            for j in range(i,0,-1):
                if li[i] < li[i-1]:
                    li[i],li[i-1] = li[i-1],li[i]
                else:
                    break
        gap = gap // 2
    return li

if __name__ == '__main__':
    lists = [17, 20, 1,999, 31, 44, 54, 55, 77, 93, 226]
    l=shell_sort(lists)
    print l

效果圖
這裡寫圖片描述