说在前面
冒泡排序是经典排序算法之一,它通过对相邻两个元素依次进行比较和调整,让较大的元素“下沉”,较小的元素“上浮”来实现排序功能。冒泡排序的原理比较简单,一般经过教师的演示以后,学生都能根据指定的排序要求和扫描方向,写出每趟排序的过程。
难点在于算法的代码实现。冒泡排序的核心代码是一个二重循环,其中内层循环描述了每轮排序的过程,根据扫描范围或方向的不同组合,可以产生各种不同的代码实现。如果学生不理解变量的含义,只会死记硬背的话,就容易产生张冠李戴的错误。如何让学生在纷繁复杂的变例拓展中抓住算法本质,是一个亟需解决的教学难题。
(资料图片)
正确理解代码的关键在于明确变量的含义。运行一段程序就好比讲述一个故事,每个代码段都对应一个故事情节,关键变量就是故事中的主人公。变量的含义不同,其所在代码段的功能也就不一样。具体到冒泡排序算法,其核心代码是一个二重循环,赋予外层循环变量i不同的含义,我们就可以从不同的角度叙述冒泡排序的故事。
冒泡排序算法任务单(学生版):
任务1. 经典冒泡排序算法。
已知数组d的初始值为[3, 2, 5, 4, 6, 1],采用冒泡排序算法对其进行从小到大排序。
(1)若采用向右扫描方式将最大值“冒泡”到右端,请写出每一趟排序后数组d的值。
(2)若采用向左扫描方式将最小值“冒泡”到左端,请写出每一趟排序后数组d的值。
(3)若采用向右扫描方式将最大值“冒泡”到右端,已知数组d的长度为n,请问总共需要排序多少趟?每趟比较次数分别为多少?总共比较次数为多少?
(4)教材p131给出了采用向右扫描方式将最大值“冒泡”到右端的算法流程图和代码实现。但是由于排版的原因,代码实现与流程图并不完全一致(变量名称不同),请修改代码,使其与流程图保持一致,分别用for循环和while循环语句来实现程序功能。
(5)若采用向左扫描方式将最小值“冒泡”到左端,请分别用for循环和while循环语句实现程序功能。体会将最小元素“上浮”和最大元素“下沉”两种方式在程序实现中的区别。
任务2. 冒泡排序优化。
经典的冒泡排序算法,对长度为n的数组需要排序n-1趟。
例如,对数组a=[5,1,3,4,2,6,7,8],需要向右扫描排序7趟,每趟排序结果如下:
第1趟:[1,3,4,2,5,6,7,8]
第2趟:[1,3,2,4,5,6,7,8]
第3趟:[1,2,3,4,5,6,7,8]
第4趟:[1,2,3,4,5,6,7,8]
第5趟:[1,2,3,4,5,6,7,8]
第6趟:[1,2,3,4,5,6,7,8]
第7趟:[1,2,3,4,5,6,7,8]
(1)仔细观察排序过程,我们可以发现第3趟冒泡后数组已经有序,后面4趟排序实际上没有做任何交换操作。当数组已经有序时,能否提前结束排序,不再做无必要的扫描?我们可以设置一个标记变量flag来标记某趟排序过程中是否发生了交换操作,若无交换操作,表示已完成排序,退出循环。
参考代码如下,请将缺失的代码补充完整。
def bubble_sort_3(a):
for i in range(1, len(a)):
swapFlag = False #先假设未做交换操作
for j in range(len(a)-i):
if a[j] > a[j+1]:
a[j], a[j+1] = 填空1
swapFlag = 填空2 #设置交互操作标志
if 填空3: #无交换操作,表示已完成排序,退出循环
break
(2)当采用向右扫描方式将最大值“冒泡”到右端时,经典的代码实现是设置二重for循环,其中外层循环变量i记录排序趟数,内层循环变量j记录当前元素的下标。
其实我们也可以从另一个角度来理解冒泡排序算法:假设当前数组中待排序序列为a[0:r+1],其中r是序列的右边界;每趟排序都是从最左端开始向右扫描待排序区域,将最大值“冒泡”到a[r]处;r的初始值为len(a)-1,每完成一趟排序,就令r=r-1;当r=0时,待排序序列中只有一个元素,排序结束。
参考代码如下,请将缺失的代码补充完整。
def bubble_sort_4(a):
for r in range(len(a)-1, 0, -1):
for j in range(填空1):#向右扫描,将最大值冒泡到a[r]
if 填空2 :
a[j], a[j+1] = a[j+1], a[j]
(3)使用函数bubble_sort_4(a)对数组a=[5,1,3,4,2,6,7,8]排序,每趟排序只让右边界r左移1位,总共需要排7趟。
观察排序过程,分析第一趟排序时,哪些元素的位置没有变化?最后一次交换操作发生在哪两个元素之间?。
一般情况下,每排序一趟就将右边界r左移一位,能否在某趟排序之后,直接将右边界移动到正确位置,以快速缩小下一趟排序的扫描范围?
我们可以设计一个冒泡排序的优化算法,通过记录最后一次发生交换操作的位置,把它作为下一趟排序的右边界,实现快速缩减扫描范围的目的。
参考代码如下,请将缺失的代码补充完整。
def bubble_sort_5(a):
right = len(a)-1
while 填空1:
swapPos = 0 #先假设最后一次发生交换操作的位置为0
for j in range(right): #顺序扫描a[0:right]
if a[j] > a[j+1]:
a[j], a[j+1] = a[j+1], a[j]
swapPos = 填空2 #记录发生交换操作的位置
right = 填空3
(4)向右扫描时,可以设置右边界,通过更新右边界,实现快速缩减扫描范围的目的。那么,能否在向左扫描时,通过快速更新左边界来提高程序效率呢?请模仿函数bubble_sort_5(a),编写向左扫描数组将最小值“冒泡”到左端的冒泡排序优化算法。
(5)既然向右扫描时可以设置右边界,向左扫描时可以设置左边界,分别都可以快速缩小扫描范围。那么能否更进一步,在内层循环中向左、向右各扫描一次,分别设置左、右边界呢?
当然可以。这种算法被称为双向冒泡排序,又称鸡尾酒排序,每轮扫描下来可以更新左、右边界,快速减少扫描范围,提高了程序效率。
参考代码如下,请将缺失的代码补充完整。
def bubble_sort_7(a):
left, right = 0, len(a)-1
while 填空1:
swapPos = left #先假设最后一次发生交换操作的位置为left
for j in range(left,right): #顺序扫描a[left:right]
if a[j] > a[j+1]:
a[j], a[j+1] = a[j+1], a[j]
swapPos =填空2
right =填空3
for j in range(right,left,-1): #逆序扫描a[left+1:right+1]
if a[j] < a[j-1]:
a[j],a[j-1] = a[j-1],a[j]
swapPos =填空4
left =填空5
总结:
冒泡排序算法采用双重for循环嵌套来实现,外层循环用来控制排序轮次(或待排序区间左边界),内层循环通过交换相邻元素的方式,将较小值向左侧冒泡。在每一轮排序结束后,都要把最小值冒泡到待排序区间最左端。
冒泡排序的比较次数与待排序元素的初始状态无关,共需要进行的比较次数是(n–1)+(n–2) + … +2+1 = n*(n–1)/2 。
冒泡排序的交换次数与待排序元素的初始状态有关,序列中逆序对的数量就等于排序过程中的交换次数。
可以使用设置交换操作标记、快速缩小右边界和双向冒泡排序等优化方法来提高冒泡排序的效率。
需要本文word文档、源代码和课后思考答案的,可以加入“Python算法之旅”知识星球参与讨论和下载文件,“Python算法之旅”知识星球汇集了数量众多的同好,更多有趣的话题在这里讨论,更多有用的资料在这里分享。
我们专注Python算法,感兴趣就一起来!
相关优秀文章:
阅读代码和写更好的代码
最有效的学习方式
Python算法之旅文章分类
-
冒泡排序算法任务单 环球视讯
说在前面冒泡排序是经典排序算法之一,它通过对相邻两个元素依次进行比较和调整,让较大的元素“下沉”,较小的元素“上浮”来实现排序功能。
-
【全球独家】环球新材国际(6616.HK):机构持仓不断加码 扩产+国际
自去年11月初以来,港股市场持续回暖,截至今年1月底,短短两个月时间,恒生指数强势上涨超50%,各大概念股,龙头个股也纷纷开启上涨行情,其
-
西安到甘南自驾游攻略四天_西安到甘南自驾游攻略
1、西安—天水—陇西—渭源(以上高速500km)—会川(316国道45km)—临洮(212国道31km)—临夏(高速93
-
天天要闻:66000余册图书|让读书爱好者享受“悦读“时光
66000余册图书|让读书爱好者享受“悦读“时光
-
环球热推荐:51岁平面模特足浴店里烫伤后背,仅能获赔75元?
采访对象供图近日,51岁的市民韩女士向新民晚报反映,她在一家足浴店里享受按摩,竟被纱袋烫伤。记者联系店方获知,双方对后续
-
三维动画制作实用教程
1、《三维动画制作实用教程》是2009年机械工业出版社出版的图书。2、。文章到此就分享结束,希望对大家有所帮助。
-
宽带账号拨号错误734错误_宽带拨号错误734是什么原因
1、错误734,ppp链接控制协议终止。2、代码734的出现也可能是由以下原因引起的:3、VPN互联网连接步骤以上就是【
-
火烧云形成的原因卡通画_火烧云形成的原因
1、火烧云在清晨,太阳刚刚出来的时候,或者傍晚太阳快要落山的时候,天边的云彩常常是通红的一片,像火烧的一样。2、人们把
-
拉萨:藏戏演出添年味 全球实时
转自:中国西藏网2月25日,藏戏经典剧目《卓娃桑姆》在拉萨市宗角禄康文化广场演出。新华社记者张汝锋摄从2月22日开始,西
-
天天快播:honeycomb
1、蜂巢型(honeycomb-likecut),一种具圆形轮廓的复杂琢型,其中央台面为近似圆形的16边形。2、周围是
-
迪普科技(300768)2月24日主力资金净卖出385.19万元 全球观热点
截至2023年2月24日收盘,迪普科技(300768)报收于16 37元,上涨2 5%,换手率1 16%,成交量4 49万手,成交额7309 83万元。
-
热讯:张天爱背后有金主?_张天爱回应背后有金主
1、张天爱2012年就已经出道,出演的角色也都是属于打酱油的,在影视圈蹉跎了4年后,接拍了让她爆红的网剧《太子妃升职记》
-
今日讯!不思议游戏之白虎传说
1、《不思议游戏之白虎传说》是一部同人类型网络小说,作者是潇湘水色。2、。文章到此就分享结束,希望对大家有所帮助。
-
我的世界拔刀剑教程第一期_我的世界拔刀剑教程 全球新要闻
1、剑图的基本属性分析:2、KillCount:击杀次数,制造一些特定的刀需要击杀次数【比如月底祭奠,击杀1000个敌人
-
东莞地铁1号线水濂山站盾构隧道贯通
东莞地铁1号线水濂山站施工现场(无人机照片,2月25日摄)。当日,由中国铁建大桥局承建的东莞地铁1号线水濂山站双线盾构隧道贯通。该段是全线
-
天天快看点丨关崇贵
1、关崇贵,男,吉林省梅河口市人。2、抗美援朝中的战斗英雄,志愿军第四十二军第一二五师第三七五团第一连副班长,机枪手。文
-
当前快讯:加速洗牌!这一指标激增74%
开年以来,随着基金发行持续回暖,基金市场也在加速洗牌,近日多只产品因资产净值低于5000万元而濒临清盘,另据wind数
-
官方通报:注意到网上涉紫航海鲜大饭店舆情 相关部门已介入 环球今热点
央广网大连2月26日消息(见习记者王松)大连市西岗区市场监督管理局26日下午在其公众号上发布情况通报。通报内容如下:情况通报近日,我们注意
-
三打
1、三打是战略打击的名称即:“打航母、打隐形飞机、打巡航导弹。2、”。文章到此就分享结束,希望对大家有所帮助。
-
圆方程求导怎么求公式_圆方程
1、圆的方程有三种,分别是X²+Y²=1;x²+y²=r²;(x-a)²+(y-b)²=r²。2、一、X²+Y²=1所表