关于递归的理解

关于递归的理解

关于递归,相信很多人最初接触的就是斐波那契数列的计算。那么这里就先不讲解斐波那契数列,先举一个简单的例子来想一想生活中的递归。
假设情人节马上到了,你收到女朋友送来的礼物,礼物是一个非常漂亮的盒子。你怀着激动的心情去拆盒子,但是第一个盒子打开里面也装着一个盒子,然后你又打开第二个盒子,发现里面又是一个盒子。嘿嘿,是不是感觉心态有点崩,最后就这样你打开了很多个盒子才找到礼物,发现里面是一个zippo打火机,开心至极。
实际上,这个找打火机的过程就引入了我们今天的主题。为了找到打火机有两种算法供你选择:

  1. 方法一:
  • 创建需要查找的盒子堆
  • 只要盒子堆不为空就打开盒子
  • 如果里面仍然是盒子就放入盒子堆;如果是打火机就说明礼物找到
  • 接下来检查盒子堆是否为空,如果不为空则继续打开;如果为空说明礼物找到
  1. 方法二:
  • 直接打开盒子,如果里面是盒子就继续打开;如果是打火机则礼物已找到
  • 如果上一步得到的结果是盒子就重复上一步操作,直至找到礼物
    这两种方法都可以找到打火机,但是我们可以发现第二种方式显得更加清晰一些,使人更容易理解,这种方式就是递归;而第一种方式实际上就是循环,循环的优点就是使程序的性能更高,具体原因稍后解释。
    在使用递归最重要的一点就是一定要先找到递归的终止条件,也就是怎么样才能让程序终止,如果不能做到这一点,这个程序将会变成死循环。
    比如我们求3!

`int test(int i)
{
if(1 == i)
return 1;

else
return i * test(i - 1);
}
int main(void)
{
int ret = 0;
ret = test(3);
printf(“ret = %d”, ret);
return 0;
}
在test函数中斜体部分就是递归终止条件,如果不写这个条件将成为死循环。
下面我们来根据代码具体说一下递归的过程(即使用调用栈的过程):

代码 调用栈情况
           test(3);                                        3入栈
         if(1 == i)                                          -
        i * test(i - 1);                                   2入栈
         if(1 == i)                                          -
        i * test(i - 1);                                   1入栈
         if(1 == i)                                         返回1
         此时还有3个test函数未调用结束,现在开始调用返回:
         当第一个test调用结束                                1出栈返回1
         当第二个test调用结束                                2出栈 返回1*2
         当第三个test调用结束                                3出栈返回2*3

所以最后的结果就是6
总的来说,整个过程也就相当于入栈出栈的过程。如果还不太清楚,可以找相关习题练习,加深理解。

发布了6 篇原创文章 · 获赞 5 · 访问量 75

猜你喜欢

转载自blog.csdn.net/weixin_42462651/article/details/104878640
今日推荐