排序算法---02 冒泡排序 Bubble sort

目   录

1. 冒泡排序描述

1.1 冒泡排序实现原理

1.2 冒泡排序性能

2. 冒泡排序实现

2.1 冒泡排序简单实现

2.2 冒泡排序优化-减少冒泡循环次数

2.3 冒泡排序优化-减少每个循环中比较的次数


1. 冒泡排序描述

1.1 冒泡排序实现原理

         冒泡排序是指从第一个元素开始,依次和周边的元素做比较,如果后面的元素比前面的小,则两者进行交换,这样两两比较和交换一轮,则最后的元素即第n个元素 就是最大的,下次只需要交换到第 n-1 个元素即可。

        这种行为有点类似于水中的气泡缓缓往上升到水面的过程,所以叫冒泡排序。

1.2 冒泡排序性能

冒泡排序性能
性能指数描述
时间复杂度(平均)o(n2),即o(n**2)在一般乱序的情况下,每轮需要比较 n 个元素和交换 m(m<n)个元素。
时间复杂度(最好)o(n)假如插入排序是正序的情况,那么优化过该算法可以得到这个最好的时间复杂度。
时间复杂度(最差)o(n2),即o(n**2)假如插入排序是倒序的情况,虽然比较的时间少了,但是挪动元素的时间是最多的,挪动比比较更花时间。
空间复杂度o(1)只需要有限的几个变量
是否稳定稳定在比较的过程中,当两个相同大小的元素相邻,只比较大或者小,所以相等的时候是不会交换位置的。而当两个相等元素离着比较远的时候,也只是会把他们交换到相邻的位置。他们的位置前后关系不会发生任何变化,所以算法是稳定的。

2. 冒泡排序实现

2.1 冒泡排序简单实现

        代码实现如下:

# 比较原始的冒泡排序方法
def Bubble_sort(nums):
    nums_len=len(nums)
    i=0
    while(i<nums_len-1):
        k=0
        while(k<nums_len-i-1):
            if(nums[k]>nums[k+1]):
                nums[k],nums[k+1]=nums[k+1],nums[k]
            k+=1
        print(nums)
        i+=1
    print(i)
    return(nums)

下面是测试代码

import random
example=list(range(20))
random.shuffle(example)
print("*"*100)
print(example)
print("*"*100)
res=Bubble_sort(example)
print("*"*100)
print(res)

测试代码运行结果如下:

        从测试代码的运行结果可以看出,此代码一共循环了 n-1 次,依次将第 n 个、第 n-1 个、第 n-2 个、第 n-3 个最大的元素放到相应的位置。

2.2 冒泡排序优化-减少冒泡循环次数

        如果修改一下待排序的数组,从下面的运行结果可以看出,在最后的 6 次循环里面,其实并没有进行任何交换,因为在前 n-2 次交换中都已经排好序了,这 6 次交换是没有意义的。 

        所以我们可以在此处进行一下优化,只有这一轮进行过交换,才会有下一轮,否则循环中止。这会很大程度的提高排序性能。 这样在非降序的情况下,可以实现最好的排序性能。

        实现代码如下:

# 优化后的 Bubble Sort 算法
# 如果上一轮有过交换,才会继续循环
def Bubble_sort(nums):
    nums_len=len(nums)
    i=0
    
    while(i<nums_len-1):
        k=0
        flag=False #  flag 用于显示是否有交换
        while(k<nums_len-i-1):
            if(nums[k]>nums[k+1]):
                nums[k],nums[k+1]=nums[k+1],nums[k]
                flag=True #产生了交换,flag 设置为 True
            k+=1
        if(not flag):
            break
        print(nums)
        i+=1
    print(i)
    return(nums)

使用相同的测试代码:

example=[10, 18, 16, 13, 1, 11, 4, 14, 8, 15, 12, 19, 2, 0, 3, 9, 17, 6, 5, 7]
print("*"*100)
print(example)
print("*"*100)
res=Bubble_sort(example)
print("*"*100)
print(res)

 测试代码运行结果如下:

可以看到不必要的循环次数已经被取消了。 

2.3 冒泡排序优化-减少每个循环中比较的次数

        # 我们除了可以设置一个标志位,来表示当前数组已经完成排序
        # 还可以记录一下上一次排序时候最后依次交换发生的地址,记成 end
        # 这样下次循环时候,只需要循环到 end 即可,实现代码如下:

# 我们除了可以设置一个标志位,来表示当前数组已经完成排序
# 还可以记录一下上一次排序时候最后依次交换发生的地址,记成 end
# 这样下次循环时候,只需要循环到 end 即可,实现代码如下:
def Bubble_sort2(nums):
    nums_len=len(nums)
    i=0
    last_end=nums_len-1
    while(i<nums_len-1):
        k=0
        flag=False #  flag 用于显示是否有交换
        end=last_end
        print("end is ==>",end)
        while(k<end):
            if(nums[k]>nums[k+1]):
                nums[k],nums[k+1]=nums[k+1],nums[k]
                flag=True #产生了交换,flag 设置为 True
                last_end=k
            k+=1
        if(not flag):
            break
        print(nums)
        i+=1
    return(nums)

测试代码如下:

import random
nums=list(range(12))
random.shuffle(nums)
print(nums)
print("*"*80)
print(Bubble_sort2(nums))

运行结果如下:

 可以看到,这样就少比较了1一个元素。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江南野栀子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值