【FBI WARNING】递归(高级数据结构的基础)

递归应该是初学者最难啃的一块骨头,很多人也是半懂不懂,结果学到很深的境地也会因为自己基础不好,导致发展太慢。

因此我希望初学者还是深刻理解递归及深搜,这样以后再继续向前学。

递归,我们把这个字分为两个部分:

递:

所谓递即向下传递,换一种理解方式就是间接或直接地调用自己本身,且递归通常把一个大型复杂的问题层层转换成一个规模较小的子问题,所以递的意思便是把问题转变成一个个的字问题,然后逐步解决。

归:

归也是初学者不明白的地方之一,难道解决完子问题就完了吗,不存在的,如果你想用子问题的值,那归的作用就体现出来了,我们可以先“递”,然后在每个最小的问题的解决的时候返回最小的问题的值,最后解决父问题。但是要注意的是递归是有边界的,即最小的子问题便是他的边界。

如果递归有这么”简单“就好了,但是可能有些人对递归的理解也仅仅到这种程度,如果上面你还不明白下面有例子。

上文的递归仅仅是对所有递归的一个概括,但递归其实可以分为两大类:

尾部递归:

  这个也是很好理解的,如果一个递归函数的尾部才是调用自己,那就是尾部递归,这个比较好理解

比如下面这个例子:

复制代码
int jiecheng(int n)
{
    if(n==1)
    return 1;
    else
    return jiecheng(n-1)*n;
 } 
复制代码

这个函数顾名思义求n的阶乘,我们先进行一波小小的数学推理,一个数的阶乘就是(这个数-1)的阶乘乘上这个数。并因此可以继续向下求这个数-1的阶乘(这便是”递“),

直到这个数到1时,便开始”归“,不断返回值,到最后返回这个数的阶乘。

emmm,这似乎很简单,但是还有一个比较难的递归。

中间递归:

  中间递归和平常的递归不一样的是在递归函数中,递归到下一层的语句后面还有语句,这时候在归上来的时候就不仅仅再返回值了,还会再执行上一层的语句,参数也执行上一次的参数,这种递归常常在搜索中被实现。

比如如果有这样的几个房间,每个房间都有两个门,有一个门都可以进入下一个房间,而另一个门则可以进入另一个房间,在这些房间里寻找宝石,如果找到就原路返回。

假设共有4个房间,且宝石在第四个房间里。

那这个题的寻找路径便为:

进入第一个房间,进入第二个房间,进入第三个房间,进入第四个房间,找到了。回到第三个房间,回到第二个房间,回到第一个房间。

拿我们的代码就是

复制代码
void 找宝石(int 当前深度)
{
  进入(深度);
  if(找到宝石)
  拿走宝石;    
  else
  找宝石(当前深度加一);//这便是递归函数。 
  离开(当前深度); 
} 
复制代码

这是我们写的代码,但是实际上被执行的代码是

复制代码
void 找宝石(2)
{
  进入(2);
  if(找到宝石)
  拿走宝石;    
  else 
  {
    进入(3);
    if(找到宝石)
    拿走宝石;
    else
    {
        进入(4) 
        if(找到宝石)
        拿走宝石;//找到了。 
        离开(4);
    }
    离开(3); 
  }
  离开(2); 
} 
复制代码

如果你还不理解,别急,再看一遍,如果再不理解,可能是我讲的不好,还是看紫书吧。

原文地址:https://www.cnblogs.com/_Yrh/p/9236099.html