冒泡排序

原理

# 列表每两个相邻的数,如果前面的数比后面的大,则交换这两个数。 
# 一趟排序完成后,则无序区减少一个数,有序区增加一个数。 
# 每循环一趟,从无序区冒出来一个最大的数,放入有序区,最终得到一个升序的列表
# 代码关键点:趟、无序区范围

代码

# -*- coding: utf-8 -*-
# created by X. Liu on 2020/3/7

def bubble_sort(li):
    n = len(li)
    for i in range(n - 1):      		# i表示循环趟数,每循环一次,就冒出来一个最大的数
        for j in range(n - 1 - i):  	# j表示每趟循环中需要前后比较两个数的次数
            if li[j] > li[j+1]:     	# 只要前面的数比后面的数大,就交换位置
                li[j+1], li[j] = li[j], li[j+1]
                
# 如果是逆序排序,只需将if判断的中的 '>' 修改为  '<'

代码解读

冒泡排序的时间复杂度:O(n^2)

# 趟:i指的是躺数,每循环一次就冒出来一个最大的数,所以一共需要循环len(li)-1次
# 无序区:每循环一趟,就会找到一个最大的数,有序的个数就会增加一个,无序区的个数就会减少一个。
# 那么每趟需要比较的次数,就是无序区长度-1;而无序区长度等于len(li)-1-i

动画演示

动画演示

改进

对于上述的冒泡排序有可以优化的地方,如果一趟循环过程中没有发生交换,则说明这趟的所有数字已经是有序的,不需要再循环下面的趟数。

# -*- coding: utf-8 -*-
# created by X. Liu on 2020/3/7

def bubble_sort(li):
    n = len(li)
    for i in range(n - 1):
        exchange = False            # 记录本趟是否发生交换
        for j in range(n - 1 - i):
            if li[j] > li[j+1]:
                li[j+1], li[j] = li[j], li[j+1]
                exchange = True     # 记录交换
        
        if not exchange:            # 如果没有交换,则已经有序,直接退出
            return

测试

# 极端情况:只需一趟循环

def bubble_sort(li):
    n = len(li)
    for i in range(n - 1):
        exchange = False            # 记录本趟是否发生交换
        for j in range(n - 1 - i):
            if li[j] > li[j+1]:
                li[j+1], li[j] = li[j], li[j+1]
                exchange = True     # 记录交换
        print(li)
        if not exchange:            # 如果没有交换,则已经有序,直接退出
            return


li = [1,2,3,4,5,6,7,8,9]
print(li)
bubble_sort(li)

# output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
posted @ 2020-03-07 21:56  the3times  阅读(225)  评论(0编辑  收藏  举报