vlambda博客
学习文章列表

用Turtle库写一个冒泡排序动画演示


* 题目 *

中国电子学会的青少年Python三级考试中,基本算法是一个重点,涉及到解析算法、枚举算法、排序算法、查找算法,而其中排序算法就有“冒泡排序”、“选择排序”、“插入排序”、“快速排序”。

网上有不少排序的动画,能够让学生形象地看到排序算法是如何对数列中的元素进行比较、交换从而实现排序的。我们是否可以用Python一、二级的知识,用Turtle库来实现同样的演示呢?




* 分析 *

Turtle库本身就是Python中自带的一种简单的绘图库,最简单的方法,我们可以用粗线来表示数值大小,用不同颜色表示操作。

我们尽可能不超纲地用Python三级前的知识点来完成一个排序算法的动画演示,超出范围的主要是def自定义函数为Python四级内容,此外导入了random库,使用shuffle函数来实现序列元素的随机排序。

以下参考程序演示中颜色说明:

黑色,未完成排序的元素;

蓝色,比较且顺序正确不用交换的元素;

红色,比较且顺序错误进行交换的元素;

绿色,已完成排序的元素。




* 执行效果 *


* 参考程序 *

import randomimport turtle
list_len = int(input('请输入排序数列长度(建议<=20):'))list_sort = list(range(1,list_len + 1))random.shuffle(list_sort)print(list_sort)
turtle.setup(800, 600)turtle.screensize(790, 590)if list_len < 2: print('数列长度不能<2') exit()else: interval = 700 / list_len line_len = 500 / list_len / 2 pen_size = 700 / list_len / 5
t = turtle.Turtle()t.hideturtle()t.setheading(90)t.speed(0)t.pensize(pen_size)posx_init = - interval * (list_len - 1) / 2
def draw_line(index, lnum, color): posx = posx_init + interval * index t.penup() t.goto(posx, -150) t.pendown() t.pencolor(color) t.forward(line_len * lnum) t.penup() t.goto(posx + 1, t.ycor()+50) t.pendown() t.pencolor('white') t.dot(20) t.goto(posx - 3, t.ycor()-10) t.pencolor(color) t.write(lnum)
t.penup()t.goto(-330, 220)t.pendown()t.write('冒泡排序过程动画演示\n\n原始数列:{}'.format(list_sort))for li, lo in enumerate(list_sort): draw_line(li, lo, 'black')
count_comp = 0count_exch = 0for li in range(list_len - 1): for lc in range(list_len - 1 -li): count_comp += 1 if list_sort[lc] > list_sort[lc+1]: count_exch += 1 draw_line(lc, list_sort[lc], 'red') draw_line(lc+1, list_sort[lc+1], 'red') draw_line(lc, list_sort[lc], 'white') draw_line(lc+1, list_sort[lc+1], 'white') list_sort[lc], list_sort[lc+1] = list_sort[lc+1], list_sort[lc] else: draw_line(lc, list_sort[lc], 'blue') draw_line(lc+1, list_sort[lc+1], 'blue') draw_line(lc, list_sort[lc], 'black') draw_line(lc+1, list_sort[lc+1], 'black') draw_line(lc+1, list_sort[lc+1], 'green') print(list_sort)draw_line(lc, list_sort[lc], 'green')
t.penup()t.goto(-330, -220)t.write('操作统计:比较%d次,交换%d次。' % (count_comp, count_exch))turtle.done()