快速理解7種排序演算法 | python3實現(

lightwing發表於2021-09-09

演算法是程式的靈魂,而排序演算法 是演算法的入門經典,作者在此用python親自實現了7種主流的排序演算法,並做簡短的說明.

圖片描述

排序演算法

學習難度:

桶排序

桶排序(簡化版)

桶排序:
將列表中最大數與最小數之間的數全部做成標籤,貼到N個桶上
將每個元素放到對應值的桶裡面(如果有M個相同的元素值,則將M個元素全部放到相應的桶中,取的時候佔用M個位置)
最後按照桶編號的先後順序,從桶中依次取出值,排列完成

__author__ = 'zhaozhao'def pail_sort(my_list):

    max_num = max(my_list)
    min_num = min(my_list)

    Y_list = list()    for i in range(min_num, max_num+1):
        zhao_list = [i, 0]
        Y_list.append(zhao_list)    for m in my_list:        for Y in Y_list:            if Y[0] == m:
                Y[1] += 1

    result = list()    for n in Y_list:        for t in range(0, n[1]):
            result.append(n[0])    return result    passdef main():

    Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20]
    print("簡單桶排序之前的序列:", Y_list)
    print("簡單桶排序之後的序列:", pail_sort(Y_list))if __name__ == '__main__':
    main()

氣泡排序

氣泡排序:
有N個待排序元素
1.設定遊標,遊標帶領第一個元素開始,與右側元素(第1個元素)比較,如果大於右側元素,則二者交換數值,然後遊標帶領元素繼續向右移動,如果小於右側元素,則不進行交換,遊標繼續向右移動,當遊標移動到列表最右側,第一輪比較就完成了(共比較N-1次)
2.然後遊標回到起始位置,開始第二輪比較,由於最後一個元素已經確定大於剩餘的元素所以(第二輪共比較N-2)次。
3.由於每次都只能選取出一個最大值,所以N個元素的陣列,進行N-1輪對比即可完成排列

__author__ = 'zhaozhao'def bubble_sort(my_list):

    N = len(my_list)    # 迴圈的次數
    circle_num = N-1

    while circle_num > 0:        # 初始的遊標值
        index_value = 0

        while index_value 

選擇排序

選擇排序(升序):
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。

__author__ = 'zhaozhao'def selection_sort(my_list):

    # N為列表元素的個數
    N = len(my_list)

    circle_num = 0

    #需要進行N-1次迴圈
    while circle_num 

插入排序

插入排序:
序列共有N個元素
將序列分為,已排序序列(第一個元素) 和 未排序序列(除第一個元素以外的其它元素,共N-1個)兩部分,然後透過N-1輪迴圈,將N-1個元素,依次新增到已排序序列中

__author__ = 'zhaozhao'def insert_sort(my_list):
    N = len(my_list)
    finish_list = list()
    f_len = len(finish_list)
    finish_list.append(my_list[0])    # circle_num為待插入的值的索引
    for circle_num in range(1, N):        for pre in range(0, circle_num):            # 如果新加入的值比已排序的值小,就把新值加入到 已排序值的前面
            if my_list[circle_num] = finish_list[-1]:
                finish_list.append(my_list[circle_num])                break
            # 如果新加入的值 比已排序的某個值大但比 已排序後面的值小
            elif my_list[circle_num] >= finish_list[pre] and my_list[circle_num] 

快速排序(面試常用演算法)

快速排序
1.選擇左側第一個元素為 基準元素(其實基準元素可以是任意值,這裡選擇第一個是為了方便敘述)

  1. 建立兩個指標, 左側指標初始位置在列表首部,右側指標初始位置在列表尾部

  2. 先移動(為了保證,兩個指標相遇時,所在位置的元素不大於 基準元素)右側指標(左移),當到達 元素值 小於基準值 的位置停止(等待左側指標的支援)

  3. 移動左側指標(右移),當到達 元素值 大於基準值 的位置停止,將此元素與 右側指標當時所在位置的值互換.

  4. 互換元素後,右側指標繼續先移動, 迴圈 3,4步驟
    6, 當左右指標相遇時, 將相遇位置的 元素值與 基準元素對調,完成第一輪迴圈
    7, 此時,基準元素左側的值都小於 基準值,基準元素右側的值都大於基準值
    8, 遞迴呼叫上面的演算法,將兩側的 元素列表 進行排序
    9, 伴隨著層層遞迴,新的基準值兩側的元素會越來越少,當基準值 無兩側元素時,排序終止

__author__ = 'zhaozhao'def q_sort(my_list, left, right):

    #設定左右指標
    left_point = left
    right_point = right
    stand_num = left    if left > right:        return

    while left_point != right_point:        #先移動右指標,如果遇到 比基準值更小 的值,就停下來

        while (my_list[right_point] >= my_list[stand_num]) and (left_point 

歸併排序(先分後和, 分而治之)

歸併排序(python內建sort方法的實現原理):
歸併排序是典型的分治法排序,將待排序元素拆成多個分組,分組內部進行排序,然後分組進行合併,最終合併成完整的陣列。

__author__ = 'zhaozhao'# 負責 將列表拆分def merge_sort(Y_list):

    if len(Y_list) 

希爾排序

希爾排序:
希爾排序是為最佳化插入排序,而建立的演算法, 其核心思想是透過設定步長 將元素分組,對每個分組進行快速排序,然後將步長減少,產生新的分組,對每個新分組進行快速排序,當步長減為1時,完成排序

__author__ = 'zhaozhao'def shell_sort(Y_list):

    gap = len(Y_list)    while gap >= 0:

        tem_list = list()        if gap == 0:            return Y_list        # 將要抽取的值和索引儲存到一個 列表裡

        for index, value in enumerate(Y_list):            if index % gap == 0:
                zhao_list = [index, value]
                tem_list.append(zhao_list)

        tem_value_list = list()        for i in tem_list:
            tem_value_list.append(i[1])
        tem_value_list = insert_sort(tem_value_list)        for i, vv in enumerate(tem_value_list):

            tem_list[i][1] = vv        # 排序好的值  替換 原位置的值
        for iv in tem_list:

            Y_list[iv[0]] = iv[1]


        gap = gap // 2


    return Y_listdef insert_sort(my_list):
    N = len(my_list)
    finish_list = list()
    f_len = len(finish_list)
    finish_list.append(my_list[0])    # circle_num為待插入的值的索引
    for circle_num in range(1, N):        for pre in range(0, circle_num):            # 如果新加入的值比已排序的值小,就把新值加入到 已排序值的前面
            if my_list[circle_num] = finish_list[-1]:
                finish_list.append(my_list[circle_num])                break
            # 如果新加入的值 比已排序的某個值大但比 已排序後面的值小
            elif my_list[circle_num] >= finish_list[pre] and my_list[circle_num] 



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3407/viewspace-2804094/,如需轉載,請註明出處,否則將追究法律責任。

相關文章