09_python_Bubble Sort and Selection Sort

邮差的信 提交于 2020-02-18 07:38:39

冒泡排序

  • 冒泡排序的算法思路在于对无序表进行多趟比较交换
    • 每趟包括了多次两两相邻比较,并将逆序的数据项交换位置,最终将本趟的最大项就位
    • 经过n-1趟比较交换,实现整表排序
    • 第n-1趟完成后,最小项一定在列表首位,无需再处理。
    • 第s趟比较交换时,需要排序的数据减少为n-s+1,共有n-s对相邻数据进行比较。

代码

def bubbleSort(alist):
    for passnum in range(len(alist)-1, 0, -1):  #n-1趟
        for i in range(passnum):
            if alist[i] > alist[i + 1]:
                alist[i],alist[i+1] = alist[i+1],alist[i]

alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
bubbleSort(alist)
print(alist)
[17, 20, 26, 31, 44, 54, 55, 77, 93]

时间复杂度分析

  • 复杂度分析:无序表初始数据项的排列状况对冒泡排序没有影响
  • 算法过程总需要n-1趟,随着趟数的增加,比对次数逐步从n-1减少到1,并包括可能发生的数据项交换:O(n^2)
    • 比对次数是1-(n-1)的累加,比对的时间复杂度为:O(n^2)
    • 交换次数不定,交换的时间复杂度是:O(n^2)
      • 最好的情况是列表在排序前已经有序,交换次数为0
      • 最差的情况是每次比对都需要进行交换,交换次数等于比对次数
      • 平均情况则是最差的情况的一半

  • 优点:无需任何额外的存储空间开销
  • 缺点:时间效率极差,因为在每个数据项找到其最终位置之前,必须要经过多次比对和交换,其中大部分的操作是无效的。

改进

  • 改进:通过检测每趟对比是否发生过交换,可以提前确定排序是否完成
    • 其他多数排序算法无法做到
    • 如果某趟比对没有发生任何交换,说明列表已经排好序,可以提前结束算法
  • “短路”优势高度依赖于数据的初始布局
    • 如果数据布局的随机度很高,造成每趟比对都会发生交换的话,shortBubbleSort就完全没有优势,还要额外付出一个exchanges变量和相应赋值语句的代价,反倒比原始的冒泡排序要慢。
def shortBubbleSort(alist):
    exchange = True
    passnum = len(alist) - 1
    while passnum > 0 and exchange:
        exchange = False
        for i in range(passnum):
            if alist[i] > alist[i + 1]:
                exchange = True
                alist[i],alist[i+1] = alist[i+1],alist[i]
        passnum = passnum - 1

alist = [20, 30, 40, 90, 50, 60,70, 80, 100, 110]
shortBubbleSort(alist)
print(alist)
[20, 30, 40, 50, 60, 70, 80, 90, 100, 110]

选择排序

  • 选择排序对冒泡排序进行了改进,保留其基本的多趟比对思路,每趟都使当前最大项就位。
    • 对交换进行了削减。每趟仅进行1趟交换,记录最大项的所在位置,最后再跟本趟最后一项交换:O(n^2)
    • 比对次数:O(n^2);交换次数:O(n)
def selectionSort(alist):
    for fillslot in range(len(alist) - 1, 0, -1):
        positionOfMax = 0
        for location in range(1, fillslot+1):
            if alist[location] > alist[positionOfMax]:
                positionOfMax = location
        alist[fillslot],alist[positionOfMax] = alist[positionOfMax],alist[fillslot]

alist = [20, 30, 40, 90, 50, 60,70, 80, 100, 110]
selectionSort(alist)
print(alist)
[20, 30, 40, 50, 60, 70, 80, 90, 100, 110]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!