日期:2020年1月7日
作者:Commas
注释:用Python3写的第一个算法博客,纪念一下
如果您想了解更多有关Python的知识,那么请点《我的Python浅谈系列目录》
一、原理及思路
1、原理
①若
从小到大
排序规则,则比较两个相邻的元素,值大
的元素交换至右端,不断重复,直至无元素交换位置
为止。
②若从大到小
排序规则,则比较两个相邻的元素,值小
的元素交换至右端,不断重复,直至无元素交换位置
为止。
2、思路
① 两次遍历列表,分内外两层遍历;
② 内层遍历主要是将一个所谓的“最大值”
送至右端,每次内层遍历结束,都会将一个“最大值”
送至“最右端”
,其次是遍历过程中,按照【原理】中的规则进行相邻值比较,会将所谓的“较大值”
尽量往右端靠拢(值大交换,值小不变);
③外层遍历主要保证每次循环
都进行了一趟“步骤②”的排序,产生一个所谓的“最大值”
在所谓的“最右端”
,当外层循环结束,则所有元素按照依次从小到大的顺序排列好。
注:“最大值”、“最右端”、“较大值”是相对而言,并非绝对存在,若不理解,可先参考输出结果理解;另外本思路是采用从小到大
的排序规则进行解释的。
二、冒泡排序示例
1、常规版冒泡排序算法:
- 应用版:
def bubble_sort(my_list, reverse=False):
"""
冒泡排序算法
:param my_list:需要排序的列表
:param reverse: 默认为升序
"""
for i in range(len(my_list)-1):
for j in range(len(my_list)-1):
if reverse:
if my_list[j] < my_list[j+1]:
my_list[j], my_list[j+1] = my_list[j+1], my_list[j]
else:
if my_list[j] > my_list[j+1]:
my_list[j], my_list[j+1] = my_list[j+1], my_list[j]
- 观察版:
def bubble_sort(my_list,reverse=True):
"""
冒泡排序算法
:param my_list:需要排序的列表
:param reverse: 默认为升序
"""
print("------冒泡排序开始------")
for i in range(len(my_list)-1):
for j in range(len(my_list)-1):
if j == 0:
print("\t第[{}]趟排序的第[{}]个动态:{}".format(i + 1, 0, my_list))
if reverse:
if my_list[j] < my_list[j+1]:
my_list[j], my_list[j+1] = my_list[j+1], my_list[j]
else:
if my_list[j] > my_list[j+1]:
my_list[j], my_list[j+1] = my_list[j+1], my_list[j]
print("\t第[{}]趟排序的第[{}]个动态:{}".format(i+1, j + 1, my_list))
print("*第[{}]趟排序结果:{}".format(i+1, my_list))
print("------冒泡排序结束------")
2、调用常规版冒泡排序并输出结果
(1)从小到大排序:
- 调用冒泡
if __name__ == '__main__':
test_list = [7, 12, 9, 1, 15, 6]
print("未排序的列表:{}".format(test_list))
bubble_sort(test_list)
print("冒泡排序后列表:{}".format(test_list))
- 控制台输出
------冒泡排序开始------
第[1]趟排序的第[0]个动态:[7, 12, 9, 1, 15, 6]
第[1]趟排序的第[1]个动态:[12, 7, 9, 1, 15, 6]
第[1]趟排序的第[2]个动态:[12, 9, 7, 1, 15, 6]
第[1]趟排序的第[3]个动态:[12, 9, 7, 1, 15, 6]
第[1]趟排序的第[4]个动态:[12, 9, 7, 15, 1, 6]
第[1]趟排序的第[5]个动态:[12, 9, 7, 15, 6, 1]
*第[1]趟排序结果:[12, 9, 7, 15, 6, 1]
第[2]趟排序的第[0]个动态:[12, 9, 7, 15, 6, 1]
第[2]趟排序的第[1]个动态:[12, 9, 7, 15, 6, 1]
第[2]趟排序的第[2]个动态:[12, 9, 7, 15, 6, 1]
第[2]趟排序的第[3]个动态:[12, 9, 15, 7, 6, 1]
第[2]趟排序的第[4]个动态:[12, 9, 15, 7, 6, 1]
第[2]趟排序的第[5]个动态:[12, 9, 15, 7, 6, 1]
*第[2]趟排序结果:[12, 9, 15, 7, 6, 1]
第[3]趟排序的第[0]个动态:[12, 9, 15, 7, 6, 1]
第[3]趟排序的第[1]个动态:[12, 9, 15, 7, 6, 1]
第[3]趟排序的第[2]个动态:[12, 15, 9, 7, 6, 1]
第[3]趟排序的第[3]个动态:[12, 15, 9, 7, 6, 1]
第[3]趟排序的第[4]个动态:[12, 15, 9, 7, 6, 1]
第[3]趟排序的第[5]个动态:[12, 15, 9, 7, 6, 1]
*第[3]趟排序结果:[12, 15, 9, 7, 6, 1]
第[4]趟排序的第[0]个动态:[12, 15, 9, 7, 6, 1]
第[4]趟排序的第[1]个动态:[15, 12, 9, 7, 6, 1]
第[4]趟排序的第[2]个动态:[15, 12, 9, 7, 6, 1]
第[4]趟排序的第[3]个动态:[15, 12, 9, 7, 6, 1]
第[4]趟排序的第[4]个动态:[15, 12, 9, 7, 6, 1]
第[4]趟排序的第[5]个动态:[15, 12, 9, 7, 6, 1]
*第[4]趟排序结果:[15, 12, 9, 7, 6, 1]
第[5]趟排序的第[0]个动态:[15, 12, 9, 7, 6, 1]
第[5]趟排序的第[1]个动态:[15, 12, 9, 7, 6, 1]
第[5]趟排序的第[2]个动态:[15, 12, 9, 7, 6, 1]
第[5]趟排序的第[3]个动态:[15, 12, 9, 7, 6, 1]
第[5]趟排序的第[4]个动态:[15, 12, 9, 7, 6, 1]
第[5]趟排序的第[5]个动态:[15, 12, 9, 7, 6, 1]
*第[5]趟排序结果:[15, 12, 9, 7, 6, 1]
------冒泡排序结束------
冒泡排序后列表:[15, 12, 9, 7, 6, 1]
(2)从大到小排序:
- 调用冒泡
if __name__ == '__main__':
test_list = [7, 12, 9, 1, 15, 6]
print("未排序的列表:{}".format(test_list))
bubble_sort(test_list, True)
print("冒泡排序后列表:{}".format(test_list))
- 控制台输出
未排序的列表:[7, 12, 9, 1, 15, 6]
------冒泡排序开始------
第[1]趟排序的第[0]个动态:[7, 12, 9, 1, 15, 6]
第[1]趟排序的第[1]个动态:[12, 7, 9, 1, 15, 6]
第[1]趟排序的第[2]个动态:[12, 9, 7, 1, 15, 6]
第[1]趟排序的第[3]个动态:[12, 9, 7, 1, 15, 6]
第[1]趟排序的第[4]个动态:[12, 9, 7, 15, 1, 6]
第[1]趟排序的第[5]个动态:[12, 9, 7, 15, 6, 1]
*第[1]趟排序结果:[12, 9, 7, 15, 6, 1]
第[2]趟排序的第[0]个动态:[12, 9, 7, 15, 6, 1]
第[2]趟排序的第[1]个动态:[12, 9, 7, 15, 6, 1]
第[2]趟排序的第[2]个动态:[12, 9, 7, 15, 6, 1]
第[2]趟排序的第[3]个动态:[12, 9, 15, 7, 6, 1]
第[2]趟排序的第[4]个动态:[12, 9, 15, 7, 6, 1]
第[2]趟排序的第[5]个动态:[12, 9, 15, 7, 6, 1]
*第[2]趟排序结果:[12, 9, 15, 7, 6, 1]
第[3]趟排序的第[0]个动态:[12, 9, 15, 7, 6, 1]
第[3]趟排序的第[1]个动态:[12, 9, 15, 7, 6, 1]
第[3]趟排序的第[2]个动态:[12, 15, 9, 7, 6, 1]
第[3]趟排序的第[3]个动态:[12, 15, 9, 7, 6, 1]
第[3]趟排序的第[4]个动态:[12, 15, 9, 7, 6, 1]
第[3]趟排序的第[5]个动态:[12, 15, 9, 7, 6, 1]
*第[3]趟排序结果:[12, 15, 9, 7, 6, 1]
第[4]趟排序的第[0]个动态:[12, 15, 9, 7, 6, 1]
第[4]趟排序的第[1]个动态:[15, 12, 9, 7, 6, 1]
第[4]趟排序的第[2]个动态:[15, 12, 9, 7, 6, 1]
第[4]趟排序的第[3]个动态:[15, 12, 9, 7, 6, 1]
第[4]趟排序的第[4]个动态:[15, 12, 9, 7, 6, 1]
第[4]趟排序的第[5]个动态:[15, 12, 9, 7, 6, 1]
*第[4]趟排序结果:[15, 12, 9, 7, 6, 1]
第[5]趟排序的第[0]个动态:[15, 12, 9, 7, 6, 1]
第[5]趟排序的第[1]个动态:[15, 12, 9, 7, 6, 1]
第[5]趟排序的第[2]个动态:[15, 12, 9, 7, 6, 1]
第[5]趟排序的第[3]个动态:[15, 12, 9, 7, 6, 1]
第[5]趟排序的第[4]个动态:[15, 12, 9, 7, 6, 1]
第[5]趟排序的第[5]个动态:[15, 12, 9, 7, 6, 1]
*第[5]趟排序结果:[15, 12, 9, 7, 6, 1]
------冒泡排序结束------
冒泡排序后列表:[15, 12, 9, 7, 6, 1]
3、优化版冒泡排序算法:
第一次优化:
每趟排序都会在“最右端”出一个“最大值”,那么以后的每趟就少遍历后面排序好的元素。
def bubble_sort(my_list, reverse=False):
"""
冒泡排序算法
:param my_list:需要排序的列表
:param reverse: 默认为升序
"""
print("------冒泡排序开始------")
last_swap_index = len(my_list)-1
for i in range(len(my_list)-1):
# 第一次优化:每一躺排序后,都已经出了一个“最大值”,所以无需再管后面排好的“最大值”
# for j in range(len(my_list)-1):
for j in range(last_swap_index):
if j == 0:
print("\t第[{}]趟排序的第[{}]个动态:{}".format(i + 1, 0, my_list))
if reverse:
if my_list[j] < my_list[j+1]:
my_list[j], my_list[j+1] = my_list[j+1], my_list[j]
last_swap_index = j
else:
if my_list[j] > my_list[j+1]:
my_list[j], my_list[j+1] = my_list[j+1], my_list[j]
last_swap_index = j
print("\t第[{}]趟排序的第[{}]个动态:{}".format(i+1, j + 1, my_list))
print("*第[{}]趟排序结果:{}".format(i+1, my_list))
print("------冒泡排序结束------")
if __name__ == '__main__':
test_list = [7, 12, 9, 1, 6, 15]
print("未排序的列表:{}".format(test_list))
bubble_sort(test_list)
print("冒泡排序后列表:{}".format(test_list))
未排序的列表:[7, 12, 9, 1, 6, 15]
------冒泡排序开始------
第[1]趟排序的第[0]个动态:[7, 12, 9, 1, 6, 15]
第[1]趟排序的第[1]个动态:[7, 12, 9, 1, 6, 15]
第[1]趟排序的第[2]个动态:[7, 9, 12, 1, 6, 15]
第[1]趟排序的第[3]个动态:[7, 9, 1, 12, 6, 15]
第[1]趟排序的第[4]个动态:[7, 9, 1, 6, 12, 15]
第[1]趟排序的第[5]个动态:[7, 9, 1, 6, 12, 15]
*第[1]趟排序结果:[7, 9, 1, 6, 12, 15]
第[2]趟排序的第[0]个动态:[7, 9, 1, 6, 12, 15]
第[2]趟排序的第[1]个动态:[7, 9, 1, 6, 12, 15]
第[2]趟排序的第[2]个动态:[7, 1, 9, 6, 12, 15]
第[2]趟排序的第[3]个动态:[7, 1, 6, 9, 12, 15]
*第[2]趟排序结果:[7, 1, 6, 9, 12, 15]
第[3]趟排序的第[0]个动态:[7, 1, 6, 9, 12, 15]
第[3]趟排序的第[1]个动态:[1, 7, 6, 9, 12, 15]
第[3]趟排序的第[2]个动态:[1, 6, 7, 9, 12, 15]
*第[3]趟排序结果:[1, 6, 7, 9, 12, 15]
第[4]趟排序的第[0]个动态:[1, 6, 7, 9, 12, 15]
第[4]趟排序的第[1]个动态:[1, 6, 7, 9, 12, 15]
*第[4]趟排序结果:[1, 6, 7, 9, 12, 15]
第[5]趟排序的第[0]个动态:[1, 6, 7, 9, 12, 15]
第[5]趟排序的第[1]个动态:[1, 6, 7, 9, 12, 15]
*第[5]趟排序结果:[1, 6, 7, 9, 12, 15]
------冒泡排序结束------
冒泡排序后列表:[1, 6, 7, 9, 12, 15]
第二次优化:
从输出结果我们可以看出,不一定要排序到最后一趟才得到最终的结果,只要无元素交换,就说明已经排序好了,就不再执行剩余趟数的排序了。如上面示例输出的结果,第[3]趟排序的第[2]个动态:[1, 6, 7, 9, 12, 15]
就已经得到我们想要的结果,但是第[3]趟有元素交换,所以在第[4]趟应该提前结束排序,优化如下:
def bubble_sort(my_list, reverse=False):
"""
冒泡排序算法
:param my_list:需要排序的列表
:param reverse: 默认为升序
"""
print("------冒泡排序开始------")
last_swap_index = len(my_list)-1
for i in range(len(my_list)-1):
no_swap = True
# 第一次优化:每一躺排序后,都已经出了一个“最大值”,所以无需再管后面排好的“最大值”
# for j in range(len(my_list)-1):
for j in range(last_swap_index):
if j == 0:
print("\t第[{}]趟排序的第[{}]个动态:{}".format(i + 1, 0, my_list))
if reverse:
if my_list[j] < my_list[j+1]:
my_list[j], my_list[j+1] = my_list[j+1], my_list[j]
last_swap_index = j
no_swap = False
else:
if my_list[j] > my_list[j+1]:
my_list[j], my_list[j+1] = my_list[j+1], my_list[j]
last_swap_index = j
no_swap = False
print("\t第[{}]趟排序的第[{}]个动态:{}".format(i+1, j + 1, my_list))
print("*第[{}]趟排序结果:{}".format(i+1, my_list))
# 第二次优化:当无元素再交换,说明排序工作已完成
if no_swap:
break
print("------冒泡排序结束------")
if __name__ == '__main__':
test_list = [7, 12, 9, 1, 6, 15]
print("未排序的列表:{}".format(test_list))
bubble_sort(test_list)
print("冒泡排序后列表:{}".format(test_list))
未排序的列表:[7, 12, 9, 1, 6, 15]
------冒泡排序开始------
第[1]趟排序的第[0]个动态:[7, 12, 9, 1, 6, 15]
第[1]趟排序的第[1]个动态:[7, 12, 9, 1, 6, 15]
第[1]趟排序的第[2]个动态:[7, 9, 12, 1, 6, 15]
第[1]趟排序的第[3]个动态:[7, 9, 1, 12, 6, 15]
第[1]趟排序的第[4]个动态:[7, 9, 1, 6, 12, 15]
第[1]趟排序的第[5]个动态:[7, 9, 1, 6, 12, 15]
*第[1]趟排序结果:[7, 9, 1, 6, 12, 15]
第[2]趟排序的第[0]个动态:[7, 9, 1, 6, 12, 15]
第[2]趟排序的第[1]个动态:[7, 9, 1, 6, 12, 15]
第[2]趟排序的第[2]个动态:[7, 1, 9, 6, 12, 15]
第[2]趟排序的第[3]个动态:[7, 1, 6, 9, 12, 15]
*第[2]趟排序结果:[7, 1, 6, 9, 12, 15]
第[3]趟排序的第[0]个动态:[7, 1, 6, 9, 12, 15]
第[3]趟排序的第[1]个动态:[1, 7, 6, 9, 12, 15]
第[3]趟排序的第[2]个动态:[1, 6, 7, 9, 12, 15]
*第[3]趟排序结果:[1, 6, 7, 9, 12, 15]
第[4]趟排序的第[0]个动态:[1, 6, 7, 9, 12, 15]
第[4]趟排序的第[1]个动态:[1, 6, 7, 9, 12, 15]
*第[4]趟排序结果:[1, 6, 7, 9, 12, 15]
------冒泡排序结束------
冒泡排序后列表:[1, 6, 7, 9, 12, 15]
版权声明:本文为博主原创文章,如需转载,请给出:
原文链接:https://blog.csdn.net/qq_35844043/article/details/103873162
来源:CSDN
作者:Commas.KM
链接:https://blog.csdn.net/qq_35844043/article/details/103873162