递归算法

递归的三大要素:

第一要素:明确你这个函数想要干什么,对于递归,我觉得很重要的一个事就是,这个函数的功能是什么,他要完成什么样的一件事,而这个,是完全由你自己来定义的。也就是说,我们先不管函数里面的代码什么,而是要先明白,你这个函数是要用来干什么。

例如,我定义了一个函数,假设是算n的阶层的函数

public void method(int n){
}

第二要素: 寻找递归结束条件,所谓递归,就是会在函数内部代码中,调用这个函数本身,所以,我们必须要找出递归的结束条件,不然的话,会一直调用自己,进入无底洞。也就是说,我们需要找出当参数为啥时,递归结束,之后直接把结果返回,请注意,这个时候我们必须能根据这个参数的值,能够直接知道函数的结果是什么。

当n等于1结果是1,当n等于2结果是2,当n=3结果是321

因此递归结束条件是n<=2

public void method(int n){
if(n<=2&&n>0){
 return n;
 }
}

第三要素:找出函数的等价关系式,第三要素就是,我们要不断缩小参数的范围,缩小之后,我们可以通过一些辅助的变量或者操作,使原函数的结果不变。
说白了,就是要找到原函数的一个等价关系式,method(n) 的等价关系式为 n * method(n-1),即method(n) = n * method(n-1)

public void method(int n){
if(n<=2&&n>0){
 return n;
 }else{

 return n * method(n-1);
}
}

案例1:

斐波那契数列:斐波那契数列的是这样一个数列:1、1、2、3、5、8、13、21、34…,即第一项 f(1) = 1,第二项 f(2) = 1…,第 n 项目为 f(n) = f(n-1) + f(n-2)。求第 n 项的值是多少。

1、第一递归函数功能: 假设 feibo(n) 的功能是求第 n 项的值,代码如下:

public void feibo(int n){
}

2、找出递归结束的条件: 显然,当 n = 1 或者 n = 2 ,我们可以轻易着知道结果 f(1) = f(2) = 1。所以递归结束条件可以为 n <= 2。代码如下:

public void feibo(int n){
if(n<=2&&n>0){
  return 1;
}
}

3、找出函数的等价关系式: 题目已经把等价关系式给我们了,所以我们很容易就能够知道 feibo(n) = feibo(n-1) + feibo(n-2)。我说过,等价关系式是最难找的一个,而这个题目却把关系式给我们了,这也太容易.

public void feibo(int n){
if(n<=2&&n>0){
  return 1;
}else{
 return feibo(n-1) + feibo(n-2);
}
}

案例2:

青蛙跳台阶问题:
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

1、第一递归函数功能: 假设 jump(n) 的功能是求青蛙跳上一个n级的台阶总共有多少种跳法,代码如下:

public void jump(int n){
}

2、找出递归结束的条件: 我说了,求递归结束的条件,你直接把 n 压缩到很小很小就行了,因为 n 越小,我们就越容易直观着算出 jump(n) 的多少,所以当 n = 1时,你知道 jump(1) 为多少吧?够直观吧?即 jump(1) = 1。当n=0时jump(0)=0,代码如下:

public void jump(int n){
if(n==1||n==0){
 return n;
}
}

3、找出函数的等价关系式
每次跳的时候,小青蛙可以跳一个台阶,也可以跳两个台阶,也就是说,每次跳的时候,小青蛙有两种跳法。

第一种跳法:第一次我跳了一个台阶,那么还剩下n-1个台阶还没跳,剩下的n-1个台阶的跳法有jump(n-1)种。

第二种跳法:第一次跳了两个台阶,那么还剩下n-2个台阶还没,剩下的n-2个台阶的跳法有jump(n-2)种。

所以,小青蛙的全部跳法就是这两种跳法之和了,即 jump(n) = jump(n-1) + jump(n-2)。至此,等价关系式就求出来了。于是写出代码:

public void jump(int n){
if(n==1||n==0){
 return n;
}else{
 return jump(n-1) + jump(n-2);
}
}

案例3:

汉诺塔问题:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4vV2gc7W-1602331426772)(http://www.ztinfo.xyz/upload/2019/12/image-8484b935abf5423ca980a4282ec0126f.png)]
如图所示8个盘子分几步才能把盘子移动到右边,可以借助左边盘子
1、第一递归函数功能: 假设Hannuo(int n,char from,char in, char to)函数是计算盘子所移动的轨迹

//n代表盘子数量
from:起始位置
in: 中间位置
to: 目标位置
public static void Hannuo(int n,char from,char in, char to){

}

2、找出递归结束的条件: 找最小假设只有1个盘子,那么从from直接到to代码如下

public static void Hannuo(int n,char from,char in, char to){
if(n == 1){ //直接从起始位置移动到目标位置
            System.out.println(n+"从"+from+"移动到"+to);
        }

}

3、找出函数的等价关系式:其实盘子数量是2个,3个,多个,都是把上面的移动到中间位置,最地下的直接移动到目的位置,然后把中间的再移动到目标位置。

public static void Hannuo(int n,char from,char in, char to){
if(n == 1){ //直接从起始位置移动到目标位置
            System.out.println(n+"从"+from+"移动到"+to);
        }else{//两个,三个,四个其实都是不等于1这种情况
            Hannuo(n-1,from,to,in); //除了最后一个盘子所有的都移动到中间位置
            System.out.println(n+"从"+from+"移动到"+to);//最下边的盘子直接移动到目标位
            Hannuo(n-1,in,from,to); //然后把中间的再移动到目标位置
     }

}

参考来源:https://www.cnblogs.com/kubidemanong/p/10538799.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值