冒泡排序
- 冒泡排序的算法思路在于对无序表进行多趟比较交换
- 每趟包括了多次两两相邻比较,并将逆序的数据项交换位置,最终将本趟的最大项就位
- 经过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]
来源:CSDN
作者:菜丁儿
链接:https://blog.csdn.net/weixin_43712064/article/details/104364092