什么是递归?

图片来源于网络

一上来你肯定觉得读这句话好绕,好吃力。 其实你用递归来读就很简单了: 递归要有一个终点(小鲤鱼) 当递归尚未达到终点的时候,函数会反复调用自己。 显然,输出"我的小鲤鱼"这句话是递归终止条件。 那么写成代码就是:

#include <stdio.h>
void Recursion(int depth){
    printf("抱着");
    if (!depth) printf("我的小鲤鱼");
    else Recursion(--depth);
    printf("的我");
}
int main(){
    printf("吓得我抱起了\n");
    Recursion(2);
    putchar('\n');
}

目前我找到的对递归最恰当的比喻,就是查词典。我们使用的词典,本身就是递归,为了解释一个词,需要使用更多的词。当你查一个词,发现这个词的解释中某个词仍然不懂,于是你开始查这第二个词,可惜,第二个词里仍然有不懂的词,于是查第三个词,这样查下去,直到有一个词的解释是你完全能看懂的,那么递归走到了尽头,然后你开始后退,逐个明白之前查过的每一个词,最终,你明白了最开始那个词的意思。。。

箭头线代表程序实际运行步骤。

看了楼上很多答案,大多偏重于描述递归的现象,而没说明为什么要用递归,递归的思想到底是什么。前阵子刚好看了点东西,试着整理下,如有错误之处,请不吝指正。

  • 什么是递归?

1. 定义

Wiki [1]:Recursion is the process of repeating items in a self-similar way.

具体到计算机中去 [2]:

递归(英语:Recursion),又译为递回,在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。

英文的Recursion从词源上分析只是"re- (again)" + "curs- (come, happen)" 也就是重复发生,再次重现的意思。 而对应的中文翻译 ”递归“ 却表达了两个意思:”递“+”归“。 这两个意思,正是递归思想的精华所在。从这层次上来看,中文翻译反而更达意。

2. 跟循环的区别

单看上面wiki的定义,貌似跟通常所说的无限死循环很像,他们的区别在哪?

递归是静中有动,有去有回。 循环是动静如一,有去无回。

举个例子,给你一把钥匙,你站在门前面,问你用这把钥匙能打开几扇门。

递归:你打开面前这扇门,看到屋里面还有一扇门(这门可能跟前面打开的门一样大小(静),也可能门小了些(动)),你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门,你继续打开,。。。, 若干次之后,你打开面前一扇门,发现只有一间屋子,没有门了。 你开始原路返回,每走回一间屋子,你数一次,走到入口的时候,你可以回答出你到底用这钥匙开了几扇门。

循环:你打开面前这扇门,看到屋里面还有一扇门,(这门可能跟前面打开的门一样大小(静),也可能门小了些(动)),你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门,(前面门如果一样,这门也是一样,第二扇门如果相比第一扇门变小了,这扇门也比第二扇门变小了(动静如一,要么没有变化,要么同样的变化)),你继续打开这扇门,。。。,一直这样走下去。 入口处的人始终等不到你回去告诉他答案。

3. 递归思想

递归就是有去(递去)有回(归来)。

具体来说,为什么可以”有去“? 这要求递归的问题需要是可以用同样的解题思路来回答类似但略有不同的问题(上面例子中的那一把钥匙可以开后面门上的锁)。

为什么可以”有回“? 这要求这些问题不断从大到小,从近及远的过程中,会有一个终点,一个临界点,一个baseline,一个你到了那个点就不用再往更小,更远的地方走下去的点,然后从那个点开始,原路返回到原点。

这篇博文[3]作者归纳为:

递归的基本思想是把规模大的问题转化为规模小的相似的子问题来解决。在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况。另外这个解决问题的函数必须有明显的结束条件,这样就不会产生无限递归的情况了。

4. 什么时候需要用递归?

当有些问题的定义本身就是递归形式的时候,最是适合用递归来解决。

计算机专业的同学最最熟悉的莫过于”“的定义了[4,5]。还有一些定义,比如阶乘,Fibonacci数列[6],等等。用递归来解决这些问题,往往几行代码就搞定了一些看起来相当”吓人“的问题。 当然,递归的性能问题是另一回事,栈的分配,函数调用代价都是在具体工程实践中要考虑的。 但现在只是讨论递归思想的话,不妨先放下那些,欣赏下递归的美。

----以上均来自网友回答

本博客所有文章如无特别注明均为原创。作者:阿珏 ,复制或转载请以超链接形式注明转自 阿珏博客 。 原文地址《什么是递归?

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 瞎折腾-友情链接自助申请

    采用Bootstrap UI库的栅格系统进行布局,毕竟咱不是专业的前端,能搞成这样就不错了。

    阿珏
  • 1024 程序员节日快乐

    10月24日被认为是程序员节。1024是2的十次方,二进制计数的基本计量单位之一。

    阿珏
  • 萌音社区来了~哇

    作为新一代开放性的二次元交流社区,图片、视频、声音,甚至是黑科技等,在允许的范围内,你几乎可以发遍任何内容.....

    阿珏
  • 讨厌算法的程序员 7 - 归并排序的时间复杂度分析

    ? 递归树 上一篇归并排序基于分治思想通过递归的调用自身完成了排序,本篇是关于归并排序的最后一部分——分析其时间复杂度。 这个过程中会解释清楚在各种时间复杂度...

    黑猿大叔
  • 《算法图解》NOTE 3 递归1.定义2递归结构2.适用场合3.应用案例

    billyang916
  • 读书笔记:《算法图解》第三章 递归

    孙亖
  • 算法导论第四章分治策略剖根问底(二)

       在上一篇中,通过一个求连续子数组的最大和的例子讲解,想必我们已经大概了然了分治策略和递归式的含义,可能会比较模糊,知道但不能用语言清晰地描述出来。但没关系...

    CloudDeveloper
  • 讨厌算法的程序员 | 第七章 归并排序的时间复杂度分析

    上一篇归并排序基于分治思想通过递归的调用自身完成了排序,本篇是关于归并排序的最后一部分——分析其时间复杂度。 这个过程中会解释清楚在各种时间复杂度中经常看到的一...

    用户1332428
  • Python之路_递归

    py3study
  • 探索c#之尾递归编译器优化

    蘑菇先生

扫码关注云+社区

领取腾讯云代金券