排序算法(归并排序法待补充)

要点概论:

1. 冒泡排序法

2. 选择排序法

3. 插入排序法

4. 快速排序法

5. 归并排序法

6. python 语言提供的排序算法

1. 冒泡排序法

  冒泡排序法时最简单的排序算法。对于包含 N 个元素的列表 A ,按递增顺序排列的冒泡法的算法如下。

  

  1)第一轮比较:从第一个元素开始,对列表中所有 N 个元素进行两两大小比较,如果不满足升序关系,则交换。

    即 A[0] 与 A[1] 比较,若A[0] > A[1] , 则 A[0] 与 A[1] 交换;然后 A[1] 与 A[2] 比较,若A[1] > A[2] ,则 A[1]  与  A[2] 交换; 

    ......直至最后 A[N -2] 与 A[N - 1] 比较, 若 A[N - 2] > A[N -1] ,则 A[N -2] 与 A[N - 1] 交换。

    第一轮比较完成后,列表元素中最大的数 “沉” 到列表最后,而那些较小的数如同气泡一样上浮一个位置,顾名思义 “冒泡法” 排序

  2)第二轮比较:从第一个元素开始,对列表中前 N - 1 个元素(第 N 个元素,即 A[N - 1]已经最大,无须参加排序)继续两两大小比较,如果不满足升序关系,则交换。

    第二轮比较完成后,列表元素中次大的数 “沉” 到最后,即 A[N - 2] 为列表元素中次大的数。

  3)以此类推,进行第 N - 1 轮比较后,列表中所有元素均按递增顺序排好序。

  PS:若要按递减顺序对列表排序,则每次两两大小比较时,如果不满足降序关系,则交换即可。

  冒泡排序法的过程如下表所示:

原始列表 2 97 86 64 50 80 3 71 8 76
第一轮比较 2 86 64 50 80 3 71 8 76 97
第二轮比较 2 64 50 80 3 71 8 76 86 97
第三轮比较 2 50 64 3 71 8 76 80 86 97
第四轮比较 2 50 3 64 8 71 76 80 86 97
第五轮比较 2 3 50 8 64 71 76 80 86 97
第六轮比较 2 3 8 50 64 71 76 80 86 97
第七轮比较 2 3 8 50 64 71 76 80 86 97
第八轮比较 2 3 8 50 64 71 76 80 86 97
第九轮比较 2 3 8 50 64 71 76 80 86 97

 

  冒泡排序算法的主要时间消耗时比较次数。

  当  i = 1 时,比较次数为 N - 1;当 i = 2 时,比较次数为 N - 2;依次类推。总共比较次数为:(N -1)+(N - 2)+ ...... + 2 + 1 = N(N -1)/ 2。

  故冒泡排序法的时间复杂度为 O(N²).

  

  冒泡排序算法的实现(bubbleSort.py):

def bubbleSort(a):
    for i in range(len(a)-1,-1,-1):     # 外循环
        for j in range(i):                     # 内循环
            if a[j] > a[j + 1]:                # 大数往下沉
                a[j],a[j + 1] = a[j + 1],a[j]
        # print(a)      # 跟踪调试

def main():
    a = [2,97,86,64,50,80,3,71,8,76]
    bubbleSort(a)
    print(a)

if __name__ == '__main__':
    main()

# 程序运行结果如下:
# [2, 3, 8, 50, 64, 71, 76, 80, 86, 97]   
bubbleSort.py

  

2. 选择排序法

  对于包含 N 个元素的列表 A ,按递增顺序排序的选择法的基本思想是:每次在若干无序数据中查找最小数,并放在无序数据中的首位。其算法如下:

  

  1)从 N 个元素的列表中找最小值及其下标,最小值与列表的第一个元素交换。

  2)从列表的第二个元素开始的 N - 1 个元素中再找最小值及其下标,该最小值(即整个列表元素的次小值)与列表第二个元素交换。

  3)以此类推,进行第 N - 1 轮选择和交换后,列表中所有元素均按递增顺序排好序。

  PS:若要按递减顺序对列表排序,只要每次查找并交换最大值即可。

  选择排序法的过程如下表所示:

原始数组 59 12 77 64 72 69 46 89 31 9
第一轮比较 9 12 77 64 72 69 46 89 31 59
第二轮比较 9 12 77 64 72 69 46 89 31 59
第三轮比较 9 12 31 64 72 69 46 89 77 59
第四轮比较 9 12 31 46 72 69 64 89 77 59
第五轮比较 9 12 31 46 59 69 64 89 77 72
第六轮比较 9 12 31 46 59 64 69 89 77 72
第七轮比较 9 12 31 46 59 64 69 89 77 72
第八轮比较 9 12 31 46 59 64 69 72 77 89
第九轮比较 9 12 31 46 59 64 69 72 77 89

  

  选择排序算法的主要时间消耗时比较次数。

  当 i = 1时,比较次数时 N - 1;当 i = 2 时,比较次数为 N - 2;以此类推。总共比较次数为:(N - 1)+(N - 2)+ ...... + 2 + 1 = N(N - 1)/ 2。

  故选择排序算法的时间复杂度为 O(N²)。

  选择排序算法的实现:

def selectionSort(a):
    for i in range(0,len(a)):            # 外循环 (0 ~ N-1)
        m = i                            # 当前位置下标
        for j in range(i+1,len(a)):     # 内循环
            if a[j] < a[m]:             # 查找最小值的位置
                m = j                   
        a[i],a[m] = a[m],a[i]           #元素交换
        # print(a)      # 跟踪调试

def main():
    a = [59,12,77,64,72,69,46,89,31,9]
    selectionSort(a)
    print(a)
    
if __name__ == '__main__':
    main()

# 程序运行结果如下:
# [9, 12, 31, 46, 59, 64, 69, 72, 77, 89]
selectionSort.py

3. 插入排序法

  对于包含 N 个元素的列表 A ,按递增顺序排序的插入排序法的基本思想是:依次检查列表中的每个元素,将其插入到其左侧已经排好序的列表中的适当位置。其算法如下:

  

  1)第二个元素与列表中其左侧的第一个元素比较,如果 A[0] > A[1] ,则交换位置,结果左侧两个元素排序完毕。

  2)第三个元素依次与其左侧的列表的元素比较,直至插入对应的排序位置,结果左侧的三个元素排序完毕。

  3)依次类推,进行第 N-1 轮比较和交换后,列表中所有元素均按递增顺序排好序。

  PS:若要按递减顺序对列表排序,只要每次查找并交换最大值即可。

  插入排序法的过程如下表所示:

原始数组 59 12 77 64 72 69 46 89 31 9
第一轮比较 12 59 77 64 72 69 46 89 31 9
第二轮比较 12 59 77 64 72 69 46 89 31 9
第三轮比较 12 59 64 77 72 69 46 89 31 9
第四轮比较 12 59 64 72 72 69 46 89 31 9
第五轮比较 12 59 64 69 72 77 46 89 31 9
第六轮比较 12 46 59 64 69 72 77 89 31 9
第七轮比较 12 46 59 64 69 72 77 89 31 9
第八轮比较 12 31 46 59 64 69 72 77 89 9
第九轮比较 9 12 31 46 59 64 69 72 77 89

  在最理想的情况下(列表处于排序状态),while 循环仅需要一次比较,故总的运行时间为线性;

  在最差的情况下(列表为逆序状态),此时内循环指令执行次数为: 1 + 2 + ...... +N - 1 = N(N - 1)/ 2 。

  故插入排序算法的时间复杂度为 O(N²) 。

   插入排序算法的实现(insertSort.py)。

def insertSort(a):
    for i in range(1,len(a)):                   # 外循环 (1 ~ N-1)
        j = i
        print(j)
        # time.sleep(1)
        while (j > 0) and (a[j] < a[j - 1]):   # 内循环
            a[j],a[j - 1] = a[j - 1],a[j]       # 元素交换
            j -= 1                              # 继续循环
            print(j)
        # print(a)      跟踪调试

def main():
    a = [59,12,77,64,72,69,46,89,31,9]
    insertSort(a)
    print(a)

if __name__ == '__main__':
    main()

# 程序运行结果如下:
# [9, 12, 31, 46, 59, 64, 69, 72, 77, 89]
insertSort.py

4. 快速排序法

  快速排序法是对冒泡排序的一种改进,其基本思想是:

  通关过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据要小;然后递归对这两部分数据分别进行快速排序。

  

  快速排序算法的一趟排序和操作步骤如下:

  1)设置两个变量 i 和 j ,分别为列表首末元素的下标,即  i = 0 ,j = N - 1。

  2)设置列表的第一个元素作为关键数据,即 key = A[0]。

  3)从 j 开始向前搜索,找到第一个小于 key 的值 A[ j ] ,将 A[ j ] 和 A[ i ] 互换。

  4)从 i  开始向后搜索,找到第一个大于 key 的值 A[ i ] ,将 A[ i ] 和 A[ j ] 互换。

  5)重复第(3)和(4)步,直到 i = j 。

  快速排序的一趟排序的算法如下表所示:

下标 0 1 2 3 4 5 6 7 8 9
原始数组 59 12 77 64 72 69 46 89 31 9
第一轮比较交换 9 12 77 64 72 69 46 89 31 59
第二轮比较交换 9 12 59 64 72 69 46 89 31 77
第三轮比较交换 9 12 31 64 72 69 46 89 59 77
第四轮比较交换 9 12 31 59 72 69 46 89 64 77
第五轮比较交换 9 12 31 46 72 69 59 89 64 77
第六轮比较交换 9 12 31 46 59 69 72 89 64 77
第七轮比较交换 9 12 31 46 59 69 72 89 64 77

  快速排序最坏情况下,每次划分选取的基准都是当前无序列表中关键字最小(或最大)的记录,时间复杂度为 O(N²)

  平均情况下,其时间复杂度为 O(Nlog2N)

  快速排序算法的实现(quickSort.py)。

def quickSort(a,low,high):      # 对列表 a 快速排序,下界为 low ,上界为 high
    i = low                     # i 等于列表下界
    j = high                    # j 等于列表上界
    if i >= j:                  # 如果下界大于等于上界,法妞结果列表 a
        return a
    key = a[i]                  # 设置列表的第一个元素作为关键数据
    # print(key)        # 跟踪调试
    while i < j:        # 循环直到 i = j
        while i < j and a[j] >= key:    # j 开始向前搜索,找到第一个小于 key 的值 a[j]
            j = j - 1
        a[i] = a[j]
        while i < j and a[i] <= key:    # i 开始向后搜索,找到第一个大于 key 的 a[i]
            i = i + 1
        a[j] = a[i]
    a[i] = key                  # a[i] 等于关键数据
    # print(a)      # 跟踪调试
    quickSort(a,low,i - 1)      # 递归调用快速排序算法(列表下界为 low ,上界为 i - 1 )
    quickSort(a,j + 1,high)     # 递归调用快速排序算法(列表下界为 j + 1 ,上界为 high)

def main():
    a = [59,12,77,64,72,69,46,89,31,9]
    quickSort(a,0,len(a) - 1)
    print(a)

if __name__ == '__main__':
    main()

# 程序运行结果如下
# [9,12,31,46,59,64,69,72,77,89]
quickSort.py

5. 归并排序法(待补充)

6. python 语言提供的排序算法

  python 语言提供了下列排序算法:

  1)内置数据类型 list 中的方法 sort() ,把列表的项按升序重新排列。

  2)内置函数 sorted() 则保持原列表不变,函数返回一个新的包含按升序排列的项的列表。

  python 系统排序方法使用了一种归并排序算法的版本,但使用了 python 无法编写的底层实现,从而避免了 python 本身附加的大量开销,故其速度比 mergeSort.py 快很多(10 ~ 20倍)。

  系统排序方法同样用于任何可比较的数据类型,例如,python 内置的 str ,int 和 float 数据类型,

  

  

原文地址:https://www.cnblogs.com/HZY258/p/8469454.html