排序算法-冒泡排序

冒泡排序就是将序列从前往后遍历,从第一个元素开始,依次与相邻的元素进行对比,若前一个元素的值大于后一个元素的值,则交换两个元素的位置,再继续与后一个元素进行对比,将较大的值逐渐向序列的尾部移动。最后得到一个有序的序列。

当遍历一次序列后,已经将序列中较大的值移动到了序列尾部,再次进行遍历序列时,就不用再与被移动到序列尾部的元素进行对比了,因为此时序列尾部的元素已经是序列中较大的元素了,并且是有序的。

例如:对序列 lst = [6, 3, 1, 7, 4,  2, 5, 10, 8, 9] 进行冒泡排序

第一次遍历:将序列中第一个较大的值移动至序列末尾

 如上图,依次遍历每个索引对应的值是否大于下一个相邻索引对应的值,大于就交换两个索引对应的值,否则就保持不变,继续遍历下一个索引,直到将第一个较大的值移动到序列的末尾。

第二次遍历:将序列中第二个较大的值移动至序列倒数第二的位置

注意:在第二次遍历的时候,遍历次数要比第一次遍历少一次,因为第一次遍历,已经将序列中最大的元素移动到了序列末尾,所以就不需要再与最后一个元素进行对比了,因为不会发生元素的交换。

第一次遍历结束后得到的序列是:[3,1,6,4,2,5,7,8,9,10]

如上图,依次进行遍历,将序列中第二大的值移动到序列倒数第二的位置。

以此类推,遍历len(lst)-1次,就可以将序列变成一个升序排列的序列。

代码如下:

lst = [6, 3, 1, 7, 4, 2, 5, 10, 8, 9]
def BubbleSort(lst):
    for i in range(len(lst)-1):
        # 遍历序列的次数
        for j in range(len(lst)-1-i):
            # 遍历序列中的每个元素,与相邻元素进行对比
            if lst[j] > lst[j+1]:
                # 当前元素大于下一个元素,就交换两个元素的值
                lst[j], lst[j+1] = lst[j+1], lst[j]
    return lst

print(BubbleSort(lst))   # 输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

上述代码可以进行优化,当遍历2次后,序列已经是有序的了,此时就可以不用再继续遍历了,例如序列为[8, 2, 3, 5, 7, 6, 9],第一次循环遍历后,得到的序列是:[2, 3, 5, 7, 6, 8, 9],第二次循环遍历后得到的序列是:[2, 3, 5, 6, 7, 8, 9],此时已经是一个有序的序列了,就没有必要去循环6次了。

优化代码如下:

lst = [8, 2, 3, 5, 7, 6, 9]
# 可以设置一个变量is_sort,值为True,每循环一次,is_sort就赋值为True,
# 当两个元素进行交换位置的时候,说明进行了排序,则将is_sort赋值为False
def BubbleSort(lst):
    # 控制循环遍历的次数,循环遍历的次数比列表的长度要少一次
    for i in range(len(lst)-1):
        is_sort = True
        # 遍历每个元素,每循环遍历一次,需要遍历比较的元素就少一个
        for j in range(len(lst)-1-i):
            if lst[j] > lst[j+1]:
                # 当前元素的值大于下一个元素的值,则交换两个元素的位置
                lst[j], lst[j+1] = lst[j+1], lst[j]
                is_sort = False
        # print("遍历了%d次"%(i+1))
        # print(lst)
        # 当本次循环遍历完后,发现没有元素之间的调换位置,则说明排序已经完成,使用break结束循环
        if is_sort:
            break
    return lst

print(BubbleSort(lst))

还可以再进行优化一次:当序列的后半部分本身就是有序的,那么每次循环遍历的时候,没有必要每次都去比较一次。

可以通过一个变量,去记录发生元素交换的位置,下一次循环遍历时,遍历元素就只遍历到发生元素交换的位置即可。例如lst = [2, 3, 1, 5, 6, 7, 8, 9],[5, 6, 7, 8, 9]已经是有序的了,可以不用每次都进行比较。

优化代码如下:

lst = [2, 3, 1, 5, 6, 7, 8, 9]
# 可以设置一个变量index,用来记录交换元素的位置,默认值为-1
# 当发生元素交换时,就将元素的索引赋值给index,下一次循环遍历时,就只遍历index索引前的元素
def BubbleSort(lst):
    # 控制循环遍历的次数,循环遍历的次数比列表的长度要少一次
    index = -1    # 记录发生元素两两交换的位置
    for i in range(len(lst)-1):
        is_sort = True    # 记录是否有发生元素的交换
        if index != -1:   # 元素交换的位置不为-1
            num = index    # 就将index赋值给num(需要遍历的元素位置)
        else:   # 当index为-1,说明是进行第一次循环遍历
            num = len(lst)-1-i
        for j in range(num):
            if lst[j] > lst[j+1]:
                # 当前元素的值大于下一个元素的值,则交换两个元素的位置
                lst[j], lst[j+1] = lst[j+1], lst[j]
                is_sort = False   # 元素进行交换了
                index = j      # 元素交换的位置
            print(f"循环了{j+1}次")
            print(lst)
        print("遍历了%d次"%(i+1))
        print(lst)
        # 当本次循环遍历完后,发现没有元素之间的调换位置,则说明排序已经完成,使用break结束循环
        if is_sort:
            break
    return lst

print(BubbleSort(lst))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值