2024年5月21日发(作者:)
201 1年第6期 福建电脑 35
如何用递归方法进行程序设计
黄欣阳,熊东平,谭敏生,阳小华
(南华大学计算机科学与技术学院湖南衡阳421005)
【摘 要】:递归方法无论在计算机科学还是在数学中都是一个重要的问题求解方法,许多复杂问题使
用递归方法能以简单易懂的形式求出问题的解。但初学者较难掌握递归方法,递归程序的设计往往成了程
序设计中的一个难点。本文通过与递推方法比较给出了递归的概念、递归与递推的区别、使用递归方法求
解的思路及关键点、保证递归方法求解正确性的条件,最后指出了递归程序设计的思路。
【关键词】:递归程序;递归方法;程序设计
在计算机科学和数学中.许多复杂问题的求解都
可以用递归方法大大简化问题的复杂性.并以简单易
懂的形式求出问题的解。但初学者较难理解递归方法,
往往感到它深不可测.更不要说用它去解决新问题了。
递归程序也成了程序设计教学中的一个难点。学生一
=5 {4 {3 {2 {l a【O】,)>) 5 {4 (3 {2 {1 1}’})
方面对复杂问题不容易理解.弄不清楚递归方法为何
能得到正确的解:另一方面自己写程序时更是没有头
这种从目的项af51出发,根据表达式(1)变为不断
绪。因此。本文试图帮助初学者解决以下几个问题:什
求前一项,直到一个已知的项,再通过不断回代计算.
么是递归方法?为何递归方法可以得到正确的解?保证
得到后续项,直到解出目的项的计算过程,称为递归方
递归方法求解正确的条件是什么?如何应用递归方法
法。
进行问题求解及如何设计递归程序?
第二种方法即递归方法能正确求解.是由于不断
1.递归方法的概念以及保证递归方法求解正确性的条 进行问题转化直到一个已知项,然后回代。在回代过程
件
中以递推方法进行。因此,只要第一步的问题转化过程
与递归方法非常相近的是递推方法。为了弄清两
正确.那么递归方法的正确性无疑等价于递推方法的
正确性。事实上,在这个例子中可以通过比较(2)和(3)来
者的关系.我们先看例题l。
例1对于数列 知道
(1) 总结例1,我们有如下概念:
a[n]=n a【n一1】
当n=O时,有a【D]=1,n为自然数,请求出a[5]。
递推方法:就是构造低阶规模(如规模为i,一般i_
分析:要求出a[5】,可以用如下两种方法: o】的问题,并求出其解,然后推导出问题规模为i+l的
第一种方法:根据公式a[n】=n掌a[n—j】,按照从前向 问题以及其解.依次推到规模为n的问题的解。简而言
后的顺序依次求出a[1l=l*a[ol=l,a【2】=2¥a【1】=2,a【3】=
之.就是从已知的当前项出发,根据表达式向后推出下
3 a【2]=3 2=6,a[4]=4*a[31=24,a[5]=5*a[4]=120。将计算
项。直到求出目的项的方法。
过程写在一起有:
递归方法:就是将规模为11的问题,降阶成若干个
一
a【5】=1 1"2 3 4 5=120 (2)
规模为n一1或规模更小的问题.用相同的方法依次降
这种从数列中的已知项a『0]开始,根据关系表达式 阶,直到问题规模可求,并求出该低阶规模问题的解。
(1)推出下一项直到计算出目的项的过程,就是递推方 代入高阶问题中,直至求出规模为n的问题的解。简而
法。这是一种很常用的方法。
言之.就是从未知的目的项出发。根据表达式转化为先
第二种方法:与第一种方法的求解方向相反。第一
求得未知的前一项。直到一个已知的项。再回代依次求
步是问题转化:根据公式a[n]=n*a[n-1],有a[5】=5 8【4】,
得后一项的解,直到求出目的项的方法。
然后有a[4】=4'lca[3],其次有a[31=3 a【2】,再次有a[2】= 递归方法的优点:在计算过程中新的未知项都与
2*a[11。最后有afl1=l书a『o1=l;第二步是以递推方法进
目的项具有相同的性质。但由于新未知项的规模变小。
行回代:将a【1]代入a【2】=2}a【1】中求出a【2】=2,然后将a 因此容易将复杂的问题简化。
『2]代入a[3]=3*a[21t9求出a[31=6,这样可以依次求出a
递归方法的正确性取决于两点:一是降低问题规模的
『41:24,a『51=120。将上述求解过程用一个式子来表示
过程正确,即转换表达式正确无误;另一点是能够将问
基金项目:湖南省2009年研究生精品课程项目(KC2009B021):南华大学2008年学位与研究生教育教学改革研究项目(2O0801);
南华大学2009高等教育研究与改革项目(O ̄Y02."2oogPYo ̄2)
36 福建 电脑 201 1年第6期
题规模降低到一个可求解的低阶规模.我们称之为边
界条件。使用递归方法求解时只要新问题与目的问题
性质相同(这样才能保证可以用相同的方法降低问题
规模)、规模越来越小并会到达边界,则该递归方法是
由于h(n一1,a,c,b)和h(n,1,b,a,c)与原问题h(n,a,b,c)
可以正确求解的。例如,f3)式所示的递归求解过程中每
次问题的规模减少1,则肯定可以到达边界规模O.因
是相同性质的问题,但规模更小,并且问题的规模只降
低1,边界条件1必然可达。于是可解得递归表达式。
此.该递归方法能得到正确的解。
2.递归方法的求解过程
解.hcn, = 后m 最威 蝴
从第一部分关于递归方法的描述可知.递归方法
进行求解的关键步骤是在降低问题规模的同时保证问
设计递归程序关键是求出递归表达式
题性质的相同性。即求出合适的转换表达式(或转换函
3.
递归方法求解实质上就是用相同的方法不断降低
数),按见名知意原则,以下称为递归表达式。用递归方
法可以对数值问题及非数值问题求解。通常,数值问题
问题规模的过程。因此。在程序设计中可以根据递归表
比较容易得到递归表达式.而非数值问题则需要经过
达式通过程序对自身的调用,即递归调用来实现。需要
注意的是:每次调用自身时,参数变小,即问题的规模
形式化转换才能得到递归表达式。下面举例说明。
变小.这一变化过程必须保证边界条件能够达到,否则
例2用递归方法求n的阶乘n!。
递归程序设计实际上是编程实
分析:要求出n!等于多少。如果能先求得fn—1)!等
程序将无法结束。因此,
于多少,然后用n半(n一1)!,即可求得n!;由于(n一1)!与n!
现递归表达式 如果知道问题的递归表达式,编递归程
属于相同性质的问题。规模变小了。因此,n!--rl*(E[一1)!,
序将变得非常容易。因为递归程序结构非常简单,只需
即是递归表达式:当规模n为0时。有01=1。该边界0
要在分支结构中以较小的参数调用自身。并注意边界
条件的处理即可。下面举例说明。
是能达到的。
解:n!的递归表达式为:
,z =
{ 木 一 )’
例3反向输出一个正整数(非数值问题)。
分析:非数值问题通常无法象数值问题那样能直
接得出递归表达式,但可以通过形式化转换来实现。假
设整数n=am l…a ao,问题即变为要反向输出aⅡl a口卜1
…a a0。为了减少问题的规模,先输出ao,还剩下am a
正如例5所示编程实现例题2是非常简单的事
…al,这时要继续对am aⅡ卜1..・a 进行反向输出,这意味
着降低了问题的规模。如果令invPrint(a.am_1..-alao)表
情。在例6中除了数值方式与非数值方式的转换存在
示反向输出am …a。ao,则有如下递归表达式。边界条
定的技巧外.总体来说是比较简单的。可见设计递归
程序关键是求出问题的递归表达式。
件m=0。即n只有一位数。是可达的。
一
4.结束语・
综述以上内容可知。设计递归程序时关键要先设
计出递归表达式。然后利用分支语句,通过递归调用来
例4汉诺塔问题的规则为:f1)一次只能移动一个
实现 递归程序设计的难点是利用降低问题规模的方
盘子;(2)大的盘子不能放在小的上面;(3)只能在三根针
法设计出递归表达式。本文给出了递归方法的概念、及
其与递推方法的区别、递归方法求解的思路、保证递归
上移动。
分析:用hfn,a,b,c)表示任务:借助b针将r1个盘子
方法求解正确性的条件及关键点。并指出了设计递归
解:invPrint( 书 然后一~
程序的思路
从a针移到c针。用降低规模法处理如下(见图1):
1、要解决原问题可先设法借助c针将a针上的
参考文献:
n一1个盘子移到b针上,表示为h(n一1,a,c,b)。
1】王慧娇,程序设计中递归函数教学问题探究O】,计算机教育,
2、此时a针上剩下一个盘子,直接将它从a针移到
【
c
针上,表示为irlove(a,c)。
2010,【1 6)
3、再设法借助a针将b针的n一1个盘子移到C针
上,表示为h(n一1,b。a,c)。
[2]-5新。浅谈C语言函数的递归调用,科技信息,2010年第27
期
[3】王岁花,马巍巍,C程序设计课程中递归教学过程设计,教育
与教学研究,2008(04)
发布者:admin,转转请注明出处:http://www.yc00.com/web/1716299919a2727179.html
评论列表(0条)