递归的正确切入方法

一、递归的定义

定义: 当函数直接或者间接调用自己时,则发生了递归。

二、理解递归

先举个递归在阶乘中的例子:阶乘的定义: “一个正整数的阶乘是所有小于或等于该数的正整数的积,并且0的阶乘为1。”

以下是C++的实现:

int factorial(int n)
{
	if(n <= 1)
		return 0;
	else
		return n * factorial(n-1);
	
}

 分析:我们很容易判断当n = 某个较小数值时这个阶乘的递归计算是否是正确。比如当n = 4时, 那么factoria(4)等于4 * factoria(3), 而factoria(3)等于3 * factoria(2)factoria(2)等于2 * factoria(1),等于2 * 1,所以factoria(4)等于4 * 3 * 2 * 1。


反思:这种分析已经有点门路了,可是怎么拓展到一般情况呢?

Paul Graham提到一种方法, 给我很大启发, 该方法如下:

  1. 当n=0,1的时候,结果正确;
  2. 假设函数对于n是正确的, 函数对n+1结果也正确。
  3. 如果这两点是成立的,我们知道这个函数对于所有可能的n都是正确的。

这种方法很像数学归纳法, 也是递归正确的思考方式, 事实上, 阶乘的递归表达方式就是1! = 1,n! = (n-1)! × n,当程序实现符合算法描述的时候, 程序自然对了, 假如还不对, 那是算法本身错了…… 相对来说,n,n+1的情况为通用情况, 虽然比较复杂, 但是还能理解, 最重要的, 也是最容易被新手忽略的问题在于第1点, 也就是基本用例(base case)要对. 比如, 上例中, 我们去掉if(n<=1)的判断后, 代码会进入死循环, 永远不会结束。

 

三、寻找问题的递归算法

 

在解题时,想运用递归却无从下手?

你只需要做两件事情:

  1. 示范如何解决问题的一般情况, 通过将问题切分成有限小并更小的子问题;
  2. 示范如何通过有限的步骤,来解决最小的问题(基本用例);
  3. 因为递归每次都将问题变得更小,而一个有限的问题终究会被解决的,而最小的问题仅需几个有限的步骤就能解决。

四、实战运用

 

汉诺塔问题:有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:1.每次只能移动一个圆盘;2.大盘不能叠在小盘上面。

 

如何使用递归?

一般情况:
当有N个圆盘在A上,我们已经找到办法将其移到C杆上了,我们怎么移动N+1个圆盘到C杆上呢? 很简单, 我们首先用将N个圆盘移动到C上的方法将N个圆盘都移动到B上, 然后再把第N+1个圆盘(最后一个)移动到C上, 再用同样的方法将在B杆上的N个圆盘移动到C上。问题解决。

基本用例:
当有1个圆盘在A上,我们直接把圆盘移动到C上即可。

 

C++代码:

 1 // 汉诺塔
 2 # include  <stdio.h>
 3 void hanoi ( int n, char a,  char b,  char c )         //这里代表将a柱子上的盘子借助b柱子移动到c柱子
 4   {  if  (1 == n)                                          //如果是一个盘子直接将a柱子上的盘子移动到c
 5          {
 6             printf("%c-->%c
",a,c);
 7           }
 8        else
 9            {
10              hanoi ( n-1,  a,  c,  b ) ;                  //将a柱子上n-1个盘子借助c柱子,移动到b柱子
11              printf("%c-->%c
",a , c) ;               //再直接将a柱子上的最后一个盘子移动到c
12              hanoi ( n-1,  b,  a,  c ) ;                  //然后将b柱子上的n-1个盘子借助a移动到c
13           }
14   }
15 int main ()
16   {  int  n ;
17       printf( "Input the number of diskes:") ;
18       scanf("%d",&n) ;
19       hanoi ( n,  'A' ,  'B' , 'C' ) ;
20       return 0;
21   }

 

原文地址:https://www.cnblogs.com/xzxl/p/7223145.html