冒泡排序及其改进

 

import random

#算法一:基本冒泡排序
def BubbleSort_1(arr):
    print("原始列表:", arr)
    compare = 0
    for i in range(len(arr)-1,0,-1):
        print("")
        for j in range(0, i):
            compare += 1
            print("比较的两个数:",arr[j], arr[j+1], "比较次数:", compare)
            if arr[j] > arr[j+1]: 
                arr[j],arr[j+1] = arr[j+1],arr[j]
                print("交换后", arr)
    print("总共比较次数:", compare)
    return arr

#算法二:冒泡排序改进,设置交换操作标志
def BubbleSort_2(arr):
    print("原始列表:", arr)
    compare = 0
    for i in range(len(arr)-1,0,-1):
        print()
        swapFlag = False #先假设未做交换操作
        for j in range(0,i):
            compare += 1
            print("比较的两个数:",arr[j], arr[j+1], "比较次数:", compare)
            if arr[j] > arr[j+1]:
                arr[j],arr[j+1] = arr[j+1],arr[j]
                print("交换后", arr)
                swapFlag = True  #设置交互操作标志
        if not swapFlag: 
            break # 无交换操作,表示已完成排序,退出循环
    print("总共比较次数:", compare)
    return arr


#算法三:双向冒泡(鸡尾酒排序),因为未发生交换操作的区域是有序的,故每轮扫描下来可以更新上下边界,减少扫描范围
def BubbleSort_3(arr):
    print("原始列表:", arr)
    compare = 0
    low, high = 0, len(arr)-1
    while low < high:
        print("")
        swapPos = low #先假设最后一次发生交换操作的位置为low
        for j in range(low,high): #顺序扫描A[low..high-1]
            compare += 1
            print("比较的两个数:",arr[j], arr[j+1], "比较次数:", compare)
            if arr[j] > arr[j+1]:
                arr[j],arr[j+1] = arr[j+1],arr[j]
                print("交换后", arr)
                swapPos = j
        print("最大值向后传播:", arr)
        high = swapPos #修改待排序数组的上界为最后一次发生交换操作的位置
        for j in range(high,low,-1): #逆序扫描A[low+1..high]
            compare += 1
            print("比较的两个数:",arr[j-1], arr[j], "比较次数:", compare)
            if arr[j-1] > arr[j]:
                arr[j],arr[j-1] = arr[j-1],arr[j]
                print("交换后", arr)
                swapPos = j
        low = swapPos #修改待排序数组的下界为最后一次发生交换操作的位置
        print("最小值向前传播:", arr)
    print("总共比较次数:", compare)
    return arr

测试使用的列表及普通冒泡排序的过程和结果如下:

a = [55, 1, 2, 3, 4, 5, 6, 12, 15]

r1 = BubbleSort_1(a.copy())
print(r1)

结果:

原始列表: [55, 1, 2, 3, 4, 5, 6, 12, 15]

比较的两个数: 55 1 比较次数: 1
交换后 [1, 55, 2, 3, 4, 5, 6, 12, 15]
比较的两个数: 55 2 比较次数: 2
交换后 [1, 2, 55, 3, 4, 5, 6, 12, 15]
比较的两个数: 55 3 比较次数: 3
交换后 [1, 2, 3, 55, 4, 5, 6, 12, 15]
比较的两个数: 55 4 比较次数: 4
交换后 [1, 2, 3, 4, 55, 5, 6, 12, 15]
比较的两个数: 55 5 比较次数: 5
交换后 [1, 2, 3, 4, 5, 55, 6, 12, 15]
比较的两个数: 55 6 比较次数: 6
交换后 [1, 2, 3, 4, 5, 6, 55, 12, 15]
比较的两个数: 55 12 比较次数: 7
交换后 [1, 2, 3, 4, 5, 6, 12, 55, 15]
比较的两个数: 55 15 比较次数: 8
交换后 [1, 2, 3, 4, 5, 6, 12, 15, 55]

比较的两个数: 1 2 比较次数: 9
比较的两个数: 2 3 比较次数: 10
比较的两个数: 3 4 比较次数: 11
比较的两个数: 4 5 比较次数: 12
比较的两个数: 5 6 比较次数: 13
比较的两个数: 6 12 比较次数: 14
比较的两个数: 12 15 比较次数: 15

比较的两个数: 1 2 比较次数: 16
比较的两个数: 2 3 比较次数: 17
比较的两个数: 3 4 比较次数: 18
比较的两个数: 4 5 比较次数: 19
比较的两个数: 5 6 比较次数: 20
比较的两个数: 6 12 比较次数: 21

比较的两个数: 1 2 比较次数: 22
比较的两个数: 2 3 比较次数: 23
比较的两个数: 3 4 比较次数: 24
比较的两个数: 4 5 比较次数: 25
比较的两个数: 5 6 比较次数: 26

比较的两个数: 1 2 比较次数: 27
比较的两个数: 2 3 比较次数: 28
比较的两个数: 3 4 比较次数: 29
比较的两个数: 4 5 比较次数: 30

比较的两个数: 1 2 比较次数: 31
比较的两个数: 2 3 比较次数: 32
比较的两个数: 3 4 比较次数: 33

比较的两个数: 1 2 比较次数: 34
比较的两个数: 2 3 比较次数: 35

比较的两个数: 1 2 比较次数: 36
总共比较次数: 36
[1, 2, 3, 4, 5, 6, 12, 15, 55]

可见总共比较了36次,其实就是8(第一轮) + 7(第二轮) + 6(。。。) + 5 + 4 + 3 + 2 + 1 = 36次

使用改进的程序测试如下:

r2 = BubbleSort_2(a.copy())
print(r2)

原始列表: [55, 1, 2, 3, 4, 5, 6, 12, 15]

比较的两个数: 55 1 比较次数: 1
交换后 [1, 55, 2, 3, 4, 5, 6, 12, 15]
比较的两个数: 55 2 比较次数: 2
交换后 [1, 2, 55, 3, 4, 5, 6, 12, 15]
比较的两个数: 55 3 比较次数: 3
交换后 [1, 2, 3, 55, 4, 5, 6, 12, 15]
比较的两个数: 55 4 比较次数: 4
交换后 [1, 2, 3, 4, 55, 5, 6, 12, 15]
比较的两个数: 55 5 比较次数: 5
交换后 [1, 2, 3, 4, 5, 55, 6, 12, 15]
比较的两个数: 55 6 比较次数: 6
交换后 [1, 2, 3, 4, 5, 6, 55, 12, 15]
比较的两个数: 55 12 比较次数: 7
交换后 [1, 2, 3, 4, 5, 6, 12, 55, 15]
比较的两个数: 55 15 比较次数: 8
交换后 [1, 2, 3, 4, 5, 6, 12, 15, 55]

比较的两个数: 1 2 比较次数: 9
比较的两个数: 2 3 比较次数: 10
比较的两个数: 3 4 比较次数: 11
比较的两个数: 4 5 比较次数: 12
比较的两个数: 5 6 比较次数: 13
比较的两个数: 6 12 比较次数: 14
比较的两个数: 12 15 比较次数: 15
总共比较次数: 15
[1, 2, 3, 4, 5, 6, 12, 15, 55]

可见这次只比较了15次就得出了结果

最终的改进为:

r3 = BubbleSort_3(a.copy())
print(r3)

原始列表: [55, 1, 2, 3, 4, 5, 6, 12, 15]

比较的两个数: 55 1 比较次数: 1
交换后 [1, 55, 2, 3, 4, 5, 6, 12, 15]
比较的两个数: 55 2 比较次数: 2
交换后 [1, 2, 55, 3, 4, 5, 6, 12, 15]
比较的两个数: 55 3 比较次数: 3
交换后 [1, 2, 3, 55, 4, 5, 6, 12, 15]
比较的两个数: 55 4 比较次数: 4
交换后 [1, 2, 3, 4, 55, 5, 6, 12, 15]
比较的两个数: 55 5 比较次数: 5
交换后 [1, 2, 3, 4, 5, 55, 6, 12, 15]
比较的两个数: 55 6 比较次数: 6
交换后 [1, 2, 3, 4, 5, 6, 55, 12, 15]
比较的两个数: 55 12 比较次数: 7
交换后 [1, 2, 3, 4, 5, 6, 12, 55, 15]
比较的两个数: 55 15 比较次数: 8
交换后 [1, 2, 3, 4, 5, 6, 12, 15, 55]
最大值向后传播: [1, 2, 3, 4, 5, 6, 12, 15, 55]
比较的两个数: 12 15 比较次数: 9
比较的两个数: 6 12 比较次数: 10
比较的两个数: 5 6 比较次数: 11
比较的两个数: 4 5 比较次数: 12
比较的两个数: 3 4 比较次数: 13
比较的两个数: 2 3 比较次数: 14
比较的两个数: 1 2 比较次数: 15
最小值向前传播: [1, 2, 3, 4, 5, 6, 12, 15, 55]
总共比较次数: 15
[1, 2, 3, 4, 5, 6, 12, 15, 55]

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值