冒泡排序法
冒泡排序法:每轮对相邻的两者进行比较,若顺序不对,则进行位置互换,每轮都将使每轮的
最后一位是该轮的大数。
比如在数列:[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),我们屏蔽掉数据打印语句(不然数据太多,干扰观察):
我想你已经看出区别了,这个区别目前很小,可是但你把数的个数继续放大,你就会发现时间的明显差距。当然了,这两种
方法还是不够快的。