數據結構與算法(十):冒泡、插入、選擇排序算法

算法原理及其比較

算法基本思想(假設原始序列爲L,長度爲n):

  • 冒泡排序:每次從序列L中選出最大元素,放到序列末尾,也即L[n]的位置,然後對剩下的序列(L[0:n-1])重複該步驟;
  • 插入排序:原始序列分爲已排序、未排序兩個序列,每次從未排序序列中取第一個元素,插入已排序序列中;
  • 選擇排序:原始序列分爲已排序、未排序兩個序列,每次從未排序序列中選出最小元素,放入已排序序列末尾;

三種排序算法的比較

  • 就空間複雜度而言,三者都是原地排序算法,空間複雜度都是O(1)
  • 就時間複雜度而言,平均時間複雜度、最壞情況時間複雜度都是O(n^2),最好情況下,也即序列已經有序的情況下,冒泡和插入算法的時間複雜度爲O(n),而選擇排序的時間複雜度仍然爲O(n^2)
  • 就算法的穩定性而言,冒泡和插入均是穩定的排序算法,而選擇屬於不穩定的排序算法;

Python實現代碼:

import copy

def bubbleSort(L, n):
    """ 冒泡排序:每次選出最大元素放在末尾
    L: 待排序列表;
    n: 列表長度;
    """
    for i in range(n):
        flag = False
        for j in range(n-i-1):
            if L[j]>L[j+1]:
                temp = L[j]
                L[j] = L[j+1]
                L[j+1] = temp
                flag = True
        if flag == False:
            break
        print(L[:n-i-1],"|", L[n-i-1:])
    return L

def insertSort(L,n):
    """ 插入排序:每次從未排序區選一個值插入已排序區
    L: 待排序列表;
    n: 列表長度;
    """
    for i in range(1,n):
        print(L[:i],"|", L[i:])
        value = L[i]
        # j的範圍是從i-1到-1,這樣做的目的是:當j比較到0位置時會有兩種情況(移動元素、不移動元素),
        # 使j最小至-1可以不必特殊處理這種情況。
        for j in range(i-1,-2,-1):
            if j == -1:
                break
            if value<L[j]:
                L[j+1] = L[j]
            else:
                break
        L[j+1] = value
    return L

def selectSort(L,n):
    """ 選擇排序:每次從未排序區選出最小元素,放在已排序區末尾
    L: 待排序列表;
    n: 列表長度;
    """
    for i in range(n):
        print(L[:i],"|", L[i:])

        minimum = L[i]
        min_idx = i
        for j in range(i,n):
            if minimum > L[j]:
                minimum = L[j]
                min_idx = j
        if min_idx != i:
            temp = L[i]
            L[i] = minimum
            L[min_idx] = temp
    return L
    
    
if __name__ == "__main__":

    L = [6,5,4,3,2,1,0]
    n = len(L)
    
    print("\n冒泡排序過程:")
    print(bubbleSort(copy.deepcopy(L),n))
    print("\n插入排序過程:")
    print(insertSort(copy.deepcopy(L),n))
    print("\n選擇排序過程:")
    print(selectSort(copy.deepcopy(L),n))

輸出結果:

冒泡排序過程:
[5, 4, 3, 2, 1, 0] | [6]
[4, 3, 2, 1, 0] | [5, 6]
[3, 2, 1, 0] | [4, 5, 6]
[2, 1, 0] | [3, 4, 5, 6]
[1, 0] | [2, 3, 4, 5, 6]
[0] | [1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]

插入排序過程:
[6] | [5, 4, 3, 2, 1, 0]
[5, 6] | [4, 3, 2, 1, 0]
[4, 5, 6] | [3, 2, 1, 0]
[3, 4, 5, 6] | [2, 1, 0]
[2, 3, 4, 5, 6] | [1, 0]
[1, 2, 3, 4, 5, 6] | [0]
[0, 1, 2, 3, 4, 5, 6]

選擇排序過程:
[] | [6, 5, 4, 3, 2, 1, 0]
[0] | [5, 4, 3, 2, 1, 6]
[0, 1] | [4, 3, 2, 5, 6]
[0, 1, 2] | [3, 4, 5, 6]
[0, 1, 2, 3] | [4, 5, 6]
[0, 1, 2, 3, 4] | [5, 6]
[0, 1, 2, 3, 4, 5] | [6]
[0, 1, 2, 3, 4, 5, 6]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章