冒泡排序:
基本原理:
1.每两两相邻的两个元素依次比较,若前一个元素比后一个元素大,则交换位置。第一轮比较完成后最大的数字就跑到了最后一个,第二轮比较完成后第二大的数字就跑到了最后倒数第二个。
2.假设数组有n个元素,则第一轮需比较n-1次,第二轮则只需比较n-2次(因为第一轮后最大的数字在最后一个,第二轮就不用比较最后一个数字),依此类推,共需比较n-1轮。
3.时间复杂度为o(n^2):因为一共需比较n*(n-1)/2次,
空间复杂度为o(1):因为没有创建新的数组,
稳定性:是个稳定的算法,如果两个数字相等,比较完成后其顺序不会发生改变。
算法优化:
1.设置全局标志位。若某轮比较后,数组顺序改变0次,即没有发生改变,数组已是有序,则后续便无需再继续比较。最好的情况,数组一开始便有序,则只需比较一轮,共比较n-1次即可,发生顺序变化0次。
2.设置最后改变标志位。若某轮比较,数组后半截顺序未发生改变,则后续比较时则无需考虑此后半截。
代码如下:
def bubble_sort(arr):
length = len(arr)
# 长度为1直接返回
if length == 1:
return arr
else:
# 记录总共比较次数
total_num = 0
# 设置最后标志位,此标志位后的元素无需再进行比较
last_flag = 0
for i in range(length-1):
flag = False
for j in range(length-last_flag-1):
total_num += 1
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
last_flag = length-(j+1)
flag = True
if not flag:
break
print('共比较了%d次。' % total_num)
return arr
if __name__ == '__main__':
lis = [2, 3, 4, 8, 5, 3, 9, 10, 12]
print(bubble_sort(lis))
# 正常比较 36次
# 设置全局标志位只比较了26次
# 继续设置最大标志位只比较了16次