有一个冲动:重温Python交换排序算法之冒泡排序

Python冒泡交换排序的思想

  • 相邻元素两两比较大小,有必要则交换。
  • 元素越小或越大,就会在数列中慢慢的交换并“浮”向顶端,如同水泡咕嘟咕嘟往上冒。

排序算法,一般都实现为就地排序,输出为升序;

  • 扩大有序区,减小无序区。图中红色部分就是增大的有序区,反之就是减小的无序区
  • 每一趟比较中,将无序区中所有元素依次两两比较,升序排序将大数调整到两数中的右侧
  • 每一趟比较完成,都会把这一趟的最大数推倒当前无序区的最右侧

Python冒泡排序算法v1.1

基本实现
思考时,将问题规模减小,一般2次不一定能找到规律,3次基本上可以看出规律。所以,我们思考时认
为列表里面就只有4个元素。

nums = [5, 1, 4, 2, 8] 

count= 0
swap_count =0
# 辅助评估算法: count表示比较的次数,count_swap表示交换的次数

for i in range(len(nums)-1):   # i 控制趟数

    # 本趟内两两比较,大数换到右边-->>>

    for j in range(len(nums) -1 -i):
        count+=1

        if nums[j] > nums[j+1]:  # 只有大于才交换,小于等于就不用了
            nums[j],nums[j+1] = nums[j+1],nums[j]
            s_c +=1            
print(nums)
print("本版本问题:没有考虑提前结束的情况,导致比较次数为",count,"次")
print("本Python冒泡排序算法版本,交换次数",swap_count)


# 如果某一趟两两比较后没有发生任何交换,说明什么?
[1, 2, 4, 5, 8]
本版本问题:没有考虑提前结束的情况,导致比较次数为 10 次
本Python冒泡排序算法版本,交换次数 0
# nums = [5, 1, 4, 2, 8]
# nums = [1,2,3,4,5,6,7,8,9] # 冒泡排序算法优化demo1:
                    #如果两两从无交换,说明已经可以大团结
nums = [9,8,1,2,3,4,5,6,7]
flag = False
count= 0
swap_count =0
for i in range(len(nums)-1):   
    
    for j in range(len(nums) -1 -i):
        count+=1

        if nums[j] > nums[j+1]:
            nums[j],nums[j+1] = nums[j+1],nums[j]
            s_c +=1
            flag = True
        
    if not flag:  # 如果两两从无交换,说明已经可以大团结,的自然表达
        break

            
print(nums)
print("本版本问题:人工可以看到只需要比较21次就够了,但是实际比较了:",count,"次")
print("本Python冒泡排序算法版本,交换次数",swap_count)

[1, 2, 3, 4, 5, 6, 7, 8, 9]
本版本问题:人工可以看到只需要比较21次就够了,但是实际比较了: 36 次
本Python冒泡排序算法版本,交换次数 0

上面代码合适吗?假设的是每一趟,只要有一趟没有发生交换,就可以认为已经是目标顺序了。要把标记放在 i 循环里。

Python冒泡排序算法v1.2

# nums = [5, 1, 4, 2, 8]
# nums = [1,2,3,4,5,6,7,8,9] #  
                    # 
nums = [9,8,1,2,3,4,5,6,7]  # flag修正 demo
# flag = False  # 修正,flag在外面会导致变为True之后,无法下次外循环中重置为False
count= 0
swap_count =0
for i in range(len(nums)-1):   
    flag = False # 修正到这里
    
    for j in range(len(nums) -1 -i):
        count+=1

        if nums[j] > nums[j+1]:
            nums[j],nums[j+1] = nums[j+1],nums[j]
            s_c +=1
            flag = True
        
    if not flag:  #  
        break

            
print(nums)
print("比较次数",count)
print("本Python冒泡排序算法版本,交换次数",swap_count)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
比较次数 21
本Python冒泡排序算法版本,交换次数 0

Python交换排序算法之冒泡总结:

  • 冒泡法需要数据一趟趟比较
  • 可以设定一个标记判断此轮是否有数据交换发生,如果没有发生交换,可以结束排序,如果发生交换,继续下一轮排序。
  • 最差的排序情况是,初始顺序与目标顺序完全相反,遍历次数1,…,n-1之和n(n-1)/2
  • 最好的排序情况是,初始顺序与目标顺序完全相同,遍历次数n-1
  • 时间复杂度O(n2) 。

Python冒泡排序算法变体

# nums = [5, 1, 4, 2, 8]
nums = [2,1,3,4,5,6,7,8,9] # 冒泡排序算法优化demo1:
                           #如果两两从无交换,说明已经可以大团结
flag = 1 
count = 0
swap_count = 0
for i in range(len(nums)-1):
    if flag == 0:
        break
    else:
        
        for j in range(len(nums) -1 -i):
            count+=1

            if nums[j] > nums[j+1]:
                nums[j],nums[j+1] = nums[j+1],nums[j]
                s_c +=1
                flag = 1
        
            
print(nums)
print("比较次数",count)
print("本Python冒泡排序算法版本,交换次数",swap_count)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
比较次数 36
本Python冒泡排序算法版本,交换次数 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值