Python教学中的递归函数教学设计
作者: 蔡毅仁
摘要:通过情景引入帮助学生对递归算法建立丰富的感性经验,激发学生的学习兴趣,进而引导学生学习递归的概念和应用条件,最后通过对6个典型案例的分析总结,帮助学生掌握递归函数的设计方法,让学生体会到递归算法解决问题的独特和高效。文章还结合Python的Turtle图像函数库进行递归作图,用直观的绘图过程促进学生对递归函数的理解和应用,取得良好的教学效果。
关键词:Python;递归函数;算法;教学设计;案例
中图分类号:TP312 文献标识码:A
文章编号:1009-3044(2022)10-0129-02
1 引言
Python语言是高中信息技术必修课程,具有开源性,语言结构和形式简洁,非常适合作为中学生的编程入门语言。在Python的教学过程中函数占据着非常重要的地位,其中递归函数既是教学重点也是教学难点。递归函数语句虽然比较简捷,但递归算法的思想学生较难理解,且函数在执行时又会调用自身,执行过程复杂,导致学生学习困难。
要理解递归函数,理解递归算法是基础。而要理解递归算法的思想,必须对递归算法有形象具体的认识。
2 直观有趣的教学情景引入
教师在开始进行递归算法的教学时,一定要先创设情景。通过生动有趣的情景来激发学生的求知欲,激发学生的学习主动性。算法教学内容本身就比较抽象,如果教师不注重创设情景,教学过程就会显得很枯燥。
递归函数的教学一般是通过斐波那契的兔子问题来引入的。斐波那契的兔子问题有趣但不够直观。事实上生活中还有更通俗易懂的递归的例子,如:让学生朗读童谣《从前有座山》,通过学生熟悉的童谣,让学生轻松愉快地接受递归概念。也可以让学生动手玩传统游戏“九连环”“汉诺塔”,通过实践了解递归的过程。通过导入情境,帮助学生建立关于递归的感性经验,同时也有效激发学生的学习兴趣。
3 递归函数概述
通过创设情景的铺垫,让学生有了充分的关于递归的经验,接下来教师就可以自然地引入递归的概念。
递归函数的典型特征是函数直接或间接调用函数本身。通过该特征,学生可以很容易学会判断一个函数是不是递归函数。但学生往往不明白函数为什么要调用函数自身,不明白什么样的问题可以用递归算法解决。
递归算法的“自己调用自己”是手段,其目的是把较大的问题不断地分解成较小的问题,直到问题可以直接得到答案[1]。
采用递归函数解决问题需要符合三个条件:
(1) 原问题可以通过较小的问题来解决;
(2) 较小的问题与原问题有相同的解法;
(3) 有一个明确的结束条件。
4 通过案例分析学习促进概念的理解
在理解了递归算法的解题思路并懂得了采用递归函数的三个条件后,还需要通过案例分析帮助学生进一步理解应用,把递归算法通过程序语言转化为递归函数的程序代码。
4.1 典型的案例1:递归法求累加
累加的一般形式为:acc (n) =1+2+3+…n。利用递归算法求累加,可表达为:
acc(n) = n+acc(n-1),n>1。acc(0)=0。
递归结束条件为:n<=1[2]。
在python中其递归函数的程序代码可以这样实现:
def acc(n): #定义累加函数acc
if n<=1: #递归结束条件
return n
else:
return n+acc(n-1) #调用函数自身
#调用递归函数 求1+2+3+…+10
print(acc(10))
4.2 典型的案例2:求阶乘n!
求阶乘:n!=n×(n-1)×(n-2)…×2×1= n×( n-1)!
利用递归算法求阶乘n!,可以把求n的阶乘的问题转化成求n-1的阶乘的问题。递归结束条件为:n<=1。在python中其递归函数的程序代码可以这样实现:
def fact(n): #定义函数fact
if n<=1: #递归结束条件
return n
else:
return n*fact(n-1) #调用函数自身
#调用递归函数fact求20!
print(fact(20))
4.3 典型的案例3:斐波那契数列
fib(n)=fib(n-1)+fib(n-2),n>1。fib(1)=1;fib(0)=0
利用递归算法求斐波那契数列,可以将求fib(n) 转化为求fib(n-1) +fib(n-2) 。递归结束条件为:n<=1。在python中其递归函数的程序代码可以这样实现:
def fib(n): #定义函数fib
if n<=1: #递归结束条件
return n
else:
return fib(n-1) + fib(n-2) #调用函数自身
print(fib(20)) #调用递归函数fib求斐波那契数列第20位的值
为了简化程序便于学生理解,上述三个例程均默认参数n>=0。
递归不但可以用于数值计算,也可以用于非数值计算的问题。Python 有绘图功能强大的turtle(海龟作图) 。将递归应用于绘图,可用简单的代码画出繁复的图形,特别能吸引学生的兴趣,有助于学生进一步理解和应用递归的思想。
4.4 典型的案例4:画螺旋线
import turtle as t #引入turtle库
def spir( len): #定义递归函数
if len > 0: #递归条件
t.forward(len) #海龟画出长为len的直线
t.right(45) #改变角度
spir(len - 1) #调用自身
#调用递归函数画螺旋线
spir(100)
4.5 典型的案例5:画树枝
import turtle as t #引入turtle库
def 画树枝(枝长): #定义递归函数
if 枝长 > 30: #递归条件
t.fd(枝长); t.rt(20)
画树枝(枝长 - 10)
t.lt(40)
画树枝(枝长 - 10)
t.rt(20) ; t.up()
t.bk(枝长); t.pd()
# 画树枝主程序
t.up()
t.left(90)
t.backward(250)
t.pd()
#调用递归函数画树枝
画树枝(100)
4.6 典型的案例6:希尔伯特曲线双递归
from turtle import * #引入turtle库
def hilL(n): #左旋
if n==0: #结束条件
pass
if n>0:
right(90)
hilR(n-1) #调用右旋
forward(l);left(90)
hilL(n-1) #调用自身
forward(l)
hilL(n-1) #调用自身
left(90);forward(l)
hilR(n-1) #调用右旋
right(90)
def hilR(n): #右旋
if n==0: #结束条件
pass
if n>0:
eft(90)
hilL(n-1) #调用左旋
forward(l);right(90)
hilR(n-1) #调用自身
forward(l)
hilR(n-1) #调用自身
right(90);forward(l)
hilL(n-1) #调用左旋
left(90)
width(3) # 设置笔刷宽度
l=10 #步幅
hilL(4) #调用递归函数,参数为曲线的阶数必须为正整数
以上6个Python教学案例代码简单、设计精巧,难度由浅入深,十分有助于学生学习和理解递归函数。特别是后面的三个采用海龟绘图的例程,绘图过程直观生动,兼具启发性和趣味性。
在教学过程中教师还可以将递归函数的执行过程做成短视频,让学生通过短视频观察代码的执行过程,再上机编程调试代码。上机时可提醒学生在执行递归函数时观察语句的执行顺序和变量的变化过程,有效加深对递归算法和函数调用过程的理解[3]。
如果有充足的时间,还可以让学生分别用循环和递归解决同一问题,通过对比来进一步理解递归的特点[4]。
5 总结与反思
学习程序设计的过程本质上是将自己的具体经验、感性形象转化为抽象的理论和概念的过程[5]。因为学生在生活中接触递归算法的机会较少,所以教师首先要帮助学生建立充分的实践体验,并激发学生的学习兴趣。在此基础上指导学生对典型案例进行观察、分析、比较和判断,让学生通过归纳、总结理解递归算法,最后通过上机编写、调试程序完成对递归函数的理解和应用。
参考文献:
[1] 唐翠娥,陈小文.递归数据结构及算法设计教学探讨[J].福建电脑,2019,35(4):130-131.
[2] 谭浩强.C语言程序设计[M].2版.北京:清华大学出版社,2008.
[3] 丁雪晶.C语言递归函数教学的设计与探讨[J].电脑知识与技术,2018,14(16):150-152.
[4] 刘瑞芳,曾海燕.递归算法的教学探讨[J].现代计算机,2009,302(3):72-73.
[5] 林东峰.中职VB课程中递归算法教学探索和思考[J].计算机光盘软件与应用, 2011(9):213-214.
【通联编辑:王力】
收稿日期:2021-06-10
作者简介:蔡毅仁,中学高级职称,本科学历,长期从事中学信息技术教学,熟悉C++、Python,擅长计算机图像处理。