冒泡排序法&定向冒泡排序法的Python实现

冒泡排序法

冒泡排序法:每轮对相邻的两者进行比较,若顺序不对,则进行位置互换,每轮都将使每轮的
最后一位是该轮的大数。
比如在数列:[71, 1, 14, 78, 75, 38, 10, 49, 40, 95]
第一轮交换:71>1 ==> [1, 71, 14, 78, 75, 38, 10, 49, 40, 95];
                      71>14 ==> [1, 14, 71, 78, 75, 38, 10, 49, 40, 95];
                      71<78 ==> pass
                      78>75 ==> [1, 14, 71, 75, 78, 38, 10, 49, 40, 95];
                      ....直到[1, 14, 71, 75, 38, 10, 49, 40, 78, 95],进行下一轮的交换
如此每一轮的比较结果:
原数据: [11, 71, 15, 65, 24, 10, 41, 23, 53, 48]
第1轮:[11, 15, 65, 24, 10, 41, 23, 53, 48, 71]
第2轮:[11, 15, 24, 10, 41, 23, 53, 48, 65, 71]
第3轮:[11, 15, 10, 24, 23, 41, 48, 53, 65, 71]
第4轮:[11, 10, 15, 23, 24, 41, 48, 53, 65, 71]
第5轮:[10, 11, 15, 23, 24, 41, 48, 53, 65, 71]
第6轮:[10, 11, 15, 23, 24, 41, 48, 53, 65, 71]
第7轮:[10, 11, 15, 23, 24, 41, 48, 53, 65, 71]
第8轮:[10, 11, 15, 23, 24, 41, 48, 53, 65, 71]
第9轮:[10, 11, 15, 23, 24, 41, 48, 53, 65, 71]
第10轮:[10, 11, 15, 23, 24, 41, 48, 53, 65, 71]

我们可以看到每一轮参与比较的数的最后一位都将是该轮最大的数。
需要注意的是:每一轮的最大数退出下一轮的比较比如第一轮比较索引值(0~9)这段位置的数,
到了第二轮就只比较索引值(0~8)这一段位置的数...。

代码实现

import time
import random
from copy import deepcopy 

def buble_order(deal):   
    op = deepcopy(deal)
    for i in range(len(op)):
        for j in range(len(op)-i-1):
            if op[j] > op[j+1]:
                temp = op[j]
                op[j] = op[j+1]
                op[j+1] = temp
            else:
                pass
        #print(op)
    return op

if __name__ == '__main__':    
    base = [random.randint(1,100) for _ in range(10)]
#    base = [71, 1, 14, 78, 75, 38, 10, 49, 40, 95]
    print('原数据:',base)
    
    start1 = time.time()
    op1 = buble_order(base)
    end1 = time.time()
    print('冒泡排序耗时:%s' % (end1-start1))
    print(op1)

冒泡排序法在时间性能上还是有些弱的,于是有人提出了定向排序法(鸡尾酒排序法)

鸡尾酒排序法

鸡尾酒排序法与冒泡排序法有一点不同的是:冒泡排序法每一轮从左向右,最终推出该轮的最大数在每一轮的右端浮现;而鸡尾
酒排序法每一轮找出该处当前轮(参与排序的数)里的最大数与最小数,置于左右两端。从左右两端缩减每一轮的排序范围。
换句话说冒泡排序法每次冒一个泡(每一轮最大的泡泡),鸡尾酒排序法每次冒两个泡(每一轮最大的泡泡和最小的泡泡),
冒泡排序法每一轮都能使靠右端的数据有序,而鸡尾酒排序法每一轮能使靠右端的数据和靠左端的数据有序,基于此,在速度
上鸡尾酒排序是比冒泡排序速度要快一点的。

代码实现

def buble_orient_order(deal):
    op = deepcopy(deal)
    
    num_min = num_max = op[0]
    index_min = index_max = 0
    left = 0#左端
    right = len(op)-1#右端
    
    while left < right:#如果设置为left != right的条件,那么就会导致奇数个数的数排序正确,偶数个数的数异常
        for i in range(left,right+1):
            if num_min > op[i]:
                num_min = op[i]
                index_min = i                 
            if num_max < op[i]:
                num_max = op[i]
                index_max = i
         
        #交换位置
        op[index_min],op[left] = op[left],op[index_min]
        op[index_max],op[right] = op[right],op[index_max]
        left += 1
        right -= 1

        num_min = num_max = op[left]
        index_min = index_max = left
        
    return op

两种排序的比较:

if __name__ == '__main__':    
    base = [random.randint(1,100) for _ in range(10)]
#    base = [71, 1, 14, 78, 75, 38, 10, 49, 40, 95]
    print('原数据:',base)
    
    start1 = time.time()
    op1 = buble_order(base)
    end1 = time.time()
    print('冒泡排序耗时:%s' % (end1-start1))
    print(op1)
    
    print('-'*25)
#    print('原数据:',base)
    
    start2 = time.time()
    op = buble_orient_order(base)
    end2 = time.time()
    print('鸡尾酒排序耗时:%s' % (end2-start2))
#    print(op)

这是我们的主函数,通过改变random.ranint()函数中的参数,调整随机取数的范围;通过调整range()函数中的参数,调整
需要排序的数的个数。
现在我们先直接在上面的参数下运行,运行结果:

可以发现两者的运行时间没什么差别,现在我们将前面提到的参数修改,我们将取数范围修改成(1,1000),取的个数修改
为(1000),我们屏蔽掉数据打印语句(不然数据太多,干扰观察):

我想你已经看出区别了,这个区别目前很小,可是但你把数的个数继续放大,你就会发现时间的明显差距。当然了,这两种
方法还是不够快的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值