用Turtle库写一个冒泡排序动画演示
* 题目 *
中国电子学会的青少年Python三级考试中,基本算法是一个重点,涉及到解析算法、枚举算法、排序算法、查找算法,而其中排序算法就有“冒泡排序”、“选择排序”、“插入排序”、“快速排序”。
网上有不少排序的动画,能够让学生形象地看到排序算法是如何对数列中的元素进行比较、交换从而实现排序的。我们是否可以用Python一、二级的知识,用Turtle库来实现同样的演示呢?
* 分析 *
Turtle库本身就是Python中自带的一种简单的绘图库,最简单的方法,我们可以用粗线来表示数值大小,用不同颜色表示操作。
我们尽可能不超纲地用Python三级前的知识点来完成一个排序算法的动画演示,超出范围的主要是def自定义函数为Python四级内容,此外导入了random库,使用shuffle函数来实现序列元素的随机排序。
以下参考程序演示中颜色说明:
黑色,未完成排序的元素;
蓝色,比较且顺序正确不用交换的元素;
红色,比较且顺序错误进行交换的元素;
绿色,已完成排序的元素。
* 执行效果 *
* 参考程序 *
import random
import 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 = 0
count_exch = 0
for 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()