Python实现冒泡排序

本文深入解析冒泡排序算法,阐述其工作原理、实现步骤及时间复杂度分析。通过实例演示冒泡排序过程,包括如何通过比较和交换操作将数据按升序排列,同时探讨了算法的最优与最坏情况下的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思想:循环遍历元素,把最大的放到最后面,或者把最小的放在最后面,这样遍历,若有n个元素,

第一个元素要比较n次,第二个元素要比较n-1次,所以我们只需构造这样一个场景即可。

通过冒泡原理的分析,冒泡排序次数m和元素比较次数j之间有如下关系:
冒泡排序次数m:1  2  3  4  5  6  7  8        范围是 for m in range(n)
元素比较次数j:8  7  6  5  4  3  2  1        范围是 for j in range(n-1,0,-1)

因为我们的冒泡排序只关心次数,所以冒泡排序次数m也可以写成 for m in range(n-1,0,-1),那么m和j效果就变成了:
冒泡排序次数m:8  7  6  5  4  3  2  1
元素比较次数j:8  7  6  5  4  3  2  1
问:为甚要关注j的排序呢?
因为j的值和元素比较的i是一一对应的

所以我们在获取冒泡排序次数m的时候,就可以直接把元素比较的次数j获取出来。

上代码:

def bubble_sort(alist):
    """实现冒泡排序的功能"""
    # 列表的长度,元素的个数
    n = len(alist)
    # 确定冒泡排序的范围,比较次数都是递减的
    for j in range(n - 1, 0, -1):
        # 开始比较前,定义计数器count的值为0
        count = 0
        # 内层数据的比较范围
        for i in range(j):
            # 逐个比较确保最大的元素放到最右面
            if alist[i] > alist[i + 1]:
                alist[i], alist[i + 1] = alist[i + 1], alist[i]
                # 数据替换完毕,计数器加1
                count += 1
        # 如果当前循环结束,但是count的值为0,没有加1,说明已经完成排序,那么结束当前循环
        if count == 0:
            break

    return alist


if __name__ == "__main__":
    alist = [9, 8, 7, 6, 6, 5, 4, 3, 2, 2, 1]
    # 原来的列表
    print("原来的列表:",alist)
    bubble_sort(alist)
    print("排序后的列表:",alist)

代码执行结果如下:

原来的列表: [9, 8, 7, 6, 6, 5, 4, 3, 2, 2, 1]
排序后的列表: [1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 9]

时间复杂度

最优时间复杂度:O(n) 
对于一个有序队列来说,内部只需要进行一次全内容遍历,就退出,内部的比较循环时间复杂度是O(n)。
对于冒泡循环,只进行了一次,所以冒泡循环的时间复杂度是O(1)
对于整体来说:最优时间复杂度就是 O(n)

最坏时间复杂度:O(n2)
最坏不过每次冒泡循环的元素比较,需要全部进行比较替换,所以每一次元素比较循环都是O(n)
那么对于总体来说,内外都是O(n),所以最坏的时间复杂度是O(n2)

稳定性:稳定

拓展:
改那个地方,结果是降序?
if alist[i] > alist[i + 1] 代码中的 > 改为 <

本节内容小结:
1、冒泡排序原理:相邻比较,大移后,数比较,大至底,数冒泡,小顺大。
2、冒泡排序实践步骤:大小比较-内部比较循环-外部冒泡循环-异常考虑

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值