递归算法详解完整版

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

递归算法详解标准化管理处编码[BBX968T-XBB8968-NNJ668-MM9N]

递归

冯文科一、递归的基本概念。

一个函数、概念或数学结构,如果在其定义或说明内部直接或间接地出现对其本身的引用,或者是为了描述问题的某一状态,必须要用至它的上一状态,而描述上一状态,又必须用到它的上一状态……这种用自己来定义自己的方法,称之为递归或递归定义。在程序设计中,函数直接或间接调用自己,就被称为递归调用。

二、递归的最简单应用:通过各项关系及初值求数列的某一项。

在数学中,有这样一种数列,很难求出它的通项公式,但数列中各项间关系却很简

a与前面临近几项之间的关单,于是人们想出另一种办法来描述这种数列:通过初值及

n

系。

要使用这样的描述方式,至少要提供两个信息:一是最前面几项的数值,一是数列间各项的关系。

比如阶乘数列

1、2、6、24、120、720……

如果用上面的方式来描述它,应该是:

a的值,那么可以很容易地写成这样:

如果需要写一个函数来求

n

这就是递归函数的最简单形式,从中可以明显看出递归函数都有的一个特点:先处理一些特殊情况——这也是递归函数的第一个出口,再处理递归关系——这形成递归函数的第二个出口。

递归函数的执行过程总是先通过递归关系不断地缩小问题的规模,直到简单到可以作为特殊情况处理而得出直接的结果,再通过递归关系逐层返回到原来的数据规模,最终得出问题的解。

以上面求阶乘数列的函数)

f为例。如在求)3(f时,由于3不是特殊值,因此需

(n

要计算)2(

3f,但)2(f是对它自己的调用,于是再计算)2(f,2也不是特殊值,需要计

*

算)1(

f,返回

)1(= 2f,需要知道)1(f的值,再计算)1(f,1是特殊值,于是直接得出1

*

上一步,得2

3

*

)2(

)3(=

=

f,从而得最终

=f

)1(

3

2

*

*

)2(=

=f

2

f,再返回上一步,得6

解。

用图解来说明,就是

下面再看一个稍复杂点的例子。

【例1】数列}{n a 的前几项为

1、111+、11111

++、111

1111+++

、……

输入n ,编程求n a 的精确分数解。

分析:

这个题目较易,发现11=a ,其它情况下有1

11-+=n n a a 。如要求实数解的话,这基本已经可以写出递归函数了。但由于题目要求精确的分数解,还需做一些调整。设p q a n =-1,则由递归关系,有q

p p p q

a a n n +=+=+=-11111,再约分化简,即得n a 。但发现

一个问题:求出1-n a 时,需要返回两个整数:分子q 与分母p ,而通常的函数只能返回一个整数。

这个问题一般有两类解决办法,一种是让求值函数返回一个结构体变量,这样就可以返回两个变量了(其实还可以不只两个呢);另一种是在求值函数的参数表中加入两个指针变量或引用变量,通过参数给带回数值。但由于后一种做法会使程序结构不清晰——返回值是由参数表得到的,因此我们使用前一种方法。

另外,在通过p q a n =-1得出q

p p a n +=后,n a 就已经是最简分数了,无须化简。证明如下: 若p

q 是最简分数,即说明q p ,的最大公约数为1,即对任何q r ≤<1,都有r q mod 与r p mod 不全为0,不防记a r q =mod 、b r p =mod ,则有

只要a 与b 不全为0,且r b r a <<,,就有a 与r b a mod )(+不全为0。因此对任何的q r ≤<1,有r p mod 与r q p mod )(+不全为0。

而对于p r q ≤<的情况而言,记a r p =mod ,则有

由于r q r a <<<≤0,0,因此同样有r p mod 与r q p mod )(+不全为0。

所以对任意p r ≤<1,都有r p mod 与r q p mod )(+不全为0,因此它们的最大公约数为1,即q

p p +是最简分数。虽然这是个要求1-n a (即p q )是最简分数的结论,但由于数

列第二项为21,是最简分数,因此可以证明第三项也是最简分数,同时也证明对所有的n a ,求出的q

p p +就是最简分数,无须化简。 具体代码如下:

)90(≤≤N N N -0i 1+i 2+i N N N i N i 12+i )1(2+i , MAX*sizeof(char)); t[n]='\0';

for(i=0;i

{

t[q[i]]='Q';

cout<

t[q[i]]='.';

}

cout<

}

bool test(int i, int k)

{

int j;

j=0;

while(j

if(j==k && mark[i]==false)

return true;

else

return false;

}

void search(int k)

{

if(k==n)

{

相关文档
最新文档