数据结构与算法(十):冒泡、插入、选择排序算法

算法原理及其比较

算法基本思想(假设原始序列为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]

 

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