递归算法的研究及经典算法的递归实现

递归算法的研究及经典算法的递归实现


2024年5月21日发(作者:)

科技信息 专题论述 

递归算法硇研夯及经典算法硇递归实坝 

常州工学院计算机信息工程学院 丁志云 

[摘要]递归思想是计算机科学的一个重要思想,递归方法是程序设计中的有效方法,它为程序设计者打开了一个全新的程序设计 

思路。采用递归思想编程,可以将一些貌似复杂的问题简单化,编写的程序更加简洁明了。本文深入分析了递归思想的特点,递归算 

法的优点和缺点,通过对多个经典算法的递归实现,让读者掌握递归算法程序设计的一些方法和技巧,有助于提高程序初学者的编 

程水平。 

[关键词]递归 算法

1.引言 

程序设计 

阶段,层层返回最终得到问题的解答。如图2所示是递归算法执行过程 

示意图。 

5.递归算法实例 

递归算法是一种直接或者间接地调用自身的算法。在计算机程序 

设计中,递归算法对解决有些问题是十分有效的,它往往使算法的描述 

简洁而且易于理解,当使用非递归方法难于解决问题时,尝试用递归方 

法也许会给你带来意想不到的惊喜。著名的汉诺塔(Hanoi)问题,八皇 

后问题,斐波那契(Fibonacci)的兔子问题,猴子吃桃问题,年龄问题等 

都是递归问题。 

2.递归算法的特点 

递归就是在过程或函数里调用自身。递归程序在执行过程中总是 

不断地调用自身,而每次调用自身时,通常在规模上都有所缩小,当问 

题的规模缩小到某一值时就可以直接给出解答而不再进行递归调用, 

因而每次递归调用都是有条件的(以规模未达到直接解答的大小为条 

件),而且相邻两次调用之间有紧密的联系,前一次要为后一次做准备 

(通常前一次的输出就作为后一次的输入),在使用递归策略时,必须有 

个明确的递归结束条件,也称为递归出口。 

递归算法一般用于解决三类问题: 

(1)数据的定义是按递归定义的,如Fibonacci函数。 

(2)问题解法按递归算法实现,如回溯问题。 

(3)数据的结构形式是按递归定义的,如树的遍历,图的搜索等。 

递归算法设计的基本思想是:对于一个复杂的问题,把原问题分解 

为若干个相对简单的同类子问题,继续下去直到子问题简单到能够直 

接求解,也就是说到了递归的出口,这样原问题就有递推得解。所以在 

使用递归算法时,首先要弄清楚简单情况下的解法,然后弄清楚如何把 

复杂情况归纳为更简单的情况。 

3.递归算法的分类 

递归算法一般通过函数或子过程来实现。在函数或子过程的内部, 

直接或者间接地调用自己的算法。所以根据递归算法的表示形式,可以 

将递归算法分为递归函数和递归子过程两种;根据递归算法调用的形 

式可以有直接递归和间接递归两种。如图1所示是直接递归和间接递 

归调用过程的示意图。 

旨 当闻{ 小 

捌薹一 

递归函数 

或子过程 问颓匍 

J、 

A ] 

l1. ̄iitB间I蠹递归 

图l直接递归和间接递归调用过程的示意图 

4.递归算法的执行过程 

开始递归过程A 递归过程A 递归过程A递归过程A 

静 

结柬 调用A—

 

 :

I 

 调用A一

r 静管  

 

图2递归算法执行过程示意图 

递归算法求解问题是通过不断调用自身来实现的,在反复调用过 

程中,通常将问题的规模不断缩小,当缩小到某一值时,就能够直接求 

解,再一一返回后求出问题的最终解。所以递归算法的执行分为两个阶 

段,第一阶段是逐层调用阶段,又称为递推阶段。在这一阶段通常是对 

个规模较大问题的求解转化成一个规模较小问题的求解,当规模小 

到某一值时,就能直接得到问题的解答,而不必再递归调用。第二阶段 

是逐层返回阶段,又称为回归阶段。当第一阶段完成后,进入逐层返回 

编写递归程序从两个方面人手,一是找出递归表达式(递归公式), 

二是确定递归的终止条件(递归出口),多数递归都有明确的递归表达 

式,此类递归算法简单明了,在编写此类递归程序时,通常只用简单的 

分支结构就可以实现。例如,求自然数n的阶乘,求斐波那契(Fibon 一 

ci)数列的第n项的值,求1-n个连续自然数的和等。下面用VB将我们 

教学中常见的经典算法用递归算法来实现。 

【例1】用递归算法求自然数n的阶乘。 

分析:要求n的阶乘,只要求出n一1的阶乘,则n!=n (n一1)!,可以定 

义一个函数fact(n),表示求n!,则递归表达式为:fact(n)=n*fact(n一1),递归 

的终止条件是当n=l或者n=0时,fact(n)=1。递归函数如下: 

Private Function fact(ByVal a As Integer)As Long 

・求n的阶乘 

If n:l Orn=0Then 

fact=1 

Else 

fact=n fact(n一11 

EndIf 

End Function 

【例2】用递归算法求斐波那契(Fibonacci)数列第n项的值。 

分析:根据Fibonacci数列的特点,可以定义一个函数fib(n),表示求 

Fibonacci数列第n项的值,则递归表达式为:ifb(n)=fib(n一1)+fib(n一2),递 

归的终止条件是当n=l或者n=2时,fib(n)=l。递归函数如下: 

Private Function ifb(ByVal n As Integer)As Integer 

’求Fibonacci数列第n项的值 

Ifn=1 Orn=2Then 

ifb=1 

Else 

ifb=fib(n一11+fib n一2、 

EndIf 

【例3】用递归算法求1~n个连续自然数的和。 

分析:可以定义一个函数sum(n),表示求l ̄n个连续自然数的和, 

则递归表达式为:sum(n)=n+sum(n—1),递归的终止条件是当n=l时,sum 

(n)=l。递归函数如下: 

Private Function sum(ByVal n As Integer)As Integer 

’求1~n个连续自然数的和 

Tfn=1 Th n 

sum=1 

Else 

sum n+sum(n一11 

EndIf 

End Function 

【例4】用递归算法实现字符串的反序。 

分析:要对一个由n个字符组成的字符串反序,只要对该字符串前 

面的n一1个字符实现反序,就可以很容易实现该字符串的反序。可以定 

义一个函数reverse(st),表示对字符串st实现反序,则递归表达式为:re— 

verse(st)=Right(st,1)&reverse(Left(st,Len(st)一1)),递归的终止条件是当 

Len(st)≤1时,reverse(s0=st。递归函数如下: 

Private Function reverse(st As Stirng)As Stirng 

’字符串反序 

IfLen(st)<=1 Then 

reverse=st 

Else 

reverse=Right(st,1)&reverse(Left(st,Len(st)一1)) 

---——

387---—— 

科技信息 专题论述 

EndIt 

End Function 

【例5】用递归算法实现将一个十进制整数转换成二进制。 

分析:可以定义一个递归函数trans(n),表示将一个十进制整数n转 

换成二进制,不难得出它的递归表达式为:trans(n)=trans(n\2)&(n Mod 

21,当n=l或者n=O时,trans(n)=n,递归函数如下: 

Private Function trans(ByVal n As Integer)As String 

’将一个十进制整数转换成二进制 

Ifn<:l Then 

trans=n 

Else 

trans:trans(n\2)&(nMod 2) 

EndIf 

End Function 

【例6】用递归算法实现求数组元素之和。 

分析:可以定义一个递归函数sum(a0,n),表示求数组a中前n个元 

素的和,则递归表达式为:sum(a0,n)=sum(a0,n一1)+a(n),当n=l时,sum(a 

0,1)=a(1),递归函数如下: 

Private Function sum(a0 As Integer,ByVal n As Integer)As Integer 

’求数组前n个元素之和 

Ifn=1 Then 

sum=a(1) 

Else 

sum=su,n(a,n—1)+a(n) 

EndIf 

End unction 

【例7】用递归算法求数组中所有数的最大值。 

分析:要求出数组中所有数的最大值,若能求出前n一1个数的最大 

值(假设数组中共有n个数),则再与第n个数比较,即可得到最大值, 

同样的要求出前n一1个数的最大值,则只要求出前n一2个数的最大值, 

再与第n一1个数比较,如此下去,当n=l时,最大值就是本身,递归结 

束。 。 

可以定义一个递归函数max(a0,n),表示求数组a中前n个数的最 

大值,则max(a0,n)=max(a0,n—1)与a(n)的比较,若a(n)>max(a0,n一1),则 

max=a(n),否则max=max(a0,n一1),递归函数如下: 

Private Function Max(a0 As Integer,ByVal n As Integer)As Integer 

’求数组前n个元素的最大值 

Ifn:1下hPn 

Max=af11 

Else 

Max=MtLx(a,n~l1 

Ifa(n1>MaxThenMax=a(n1 

EndIf 

End Function 

【例8】用递归算法判断一个数是否是回文数。 

分析:要判断一个数是否是回文数,只要判断首尾数字字符是否相 

等,若不等,则不是回文数,若相等,则去掉该数的首尾数字字符,再判 

断去掉首尾字符后的新数字是否是回文数,如此下去,当新数字的长度 

小于等于1时,是回文数(已知)。递归函数如下: 

Private Function hws(ByVal st As Stirng)As Boolean 

’判断一个数是否是回文数 

IfLen(st1<:1 Then 

hws=True 

Exit Function 

Elself Left(st,1)<>Right(st,1)Then 

Exit Function 

EndIf 

hws=hws(Mid(st,2,Len(st)一2)) 

End Function 

【例9】用递归算法求一个正整数的所有因子,并存放在一个数组 

中。 

分析:可以定义一个递归子过程gen(n,nl,aO),功能是判断In是否是 

正整数n的一个因子,若是则将In存放在数组中,m从1开始,当m>n 

时,递归结束,否则m+l,再调用该递归子过程。递归子过程如下: 

Private Sub gen(ByVal n As Integer,m As Integer,a0 As Integer) 

’求一个正整数的所有因子,存放在一个数组中 

Static k As Integer 

IfnModm=0ThPn 

388...—— 

k=k+l 

ReDim Preserve a(k) 

a(k)=m 

EndIf 

Ifm>nThen 

Exit Sub 

Else 

Call gen(n,m+1,a) 

EndIf 

End Sub 

【例10】用递归算法实现数组的从大到小排序。 

分析:要对数组a中所有元素进行排序,若能对前n一1个元素进行 

排序(假设数组a中共有n个元素),则在排序好的n一1个元素中找到 

插人位置,再将a(n)插入到该位置即可,同样的要对数组a中n一1个元 

素进行排序,则先排序好n一2个元素,如此下去,当n=1时,递归结束。 

可以定义一个递归子过程sort(aO,n),功能是实现数组a中前n个元素 

排序。递归子过程如下: 

Private Sub sort(a0 As Integer,n As Integer) 

对数组前n个元素进行排序 

Dim i As Integer,pos As Integer 

Dim temp As Integer 

Ifn>1 Then 

Call sort(a,n一1) 

Fori=1 Ton一1’找插入位置 

Ifa(n1>=a(i1 Then 

Exit For 

EndIf 

Next 

pos 1 

temp a(n1 

Fori=n一1 Topos Step一1’循环移位 

a“+1):a(i1 

Nexti 

a(pos1=temp 

EndIf 

End Sub 

【例1 1】用递归算法实现判断一个正整数n是否是素数。 

分析:可以定义一个递归函数prime(n,m),功能是判断m是否能被 

正整数n整除,若能则该正整数n不是素数,m从2开始,当m=n时,递 

归结束,否则m+l,再调用该递归函数。递归甬数如下: 

Private Function prime(ByVal n As Integer,m As Integer)As Boolean 

’判断一个正整数n是否是素数 

Ifm=nThen 

prime=True 

ElseIfn<2OrnModin=0Then 

prime=False 

Else 

prime=prime(n,m+I) 

EndIf 

End Function 

6.小结 

递归算法不仅仅可以用于求解递归描述的问题,在其它很多问题 

中也可以用到递归思想,如回溯法、分治法、动态规划法等算法中都可 

以使用递归思想来实现,递归的思维与人们的常规思维是相逆的 

用递归算法编写的程序虽然简洁明_『,但递归算法解题的运行效 

率较低。在递归调用的过程中系统为每一层的返回点、局部量等开辟了 

栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算 

法设计程序。例如以上介绍的求斐波那契(Fibonacci)数列第n项值的 

递归过程,调用一次要产生两个新的调用,递归次数呈指数增长,时间 

复杂度为O(2n),若用非递归法求解,它的时间复杂度为O(n)。 

参考文献 

[1]钟秀玉,陈月峰.基于递归与多线程的丢失文件查找设计[J].计 

算机技术与发展,2010. 

[2]苗英恺递归程序的教学探讨[I]电脑知识与技术,2008. 

[3]符策锐基于vB的递归模拟演示程序的实现[J].电脑开发与应 

用、2008 


发布者:admin,转转请注明出处:http://www.yc00.com/news/1716299163a2727175.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信