要理解递归,你先要理解递归

本文将介绍递归的概念和简单的例子,希望能够帮助读者理解计算机中难以理解的递归。


1.什么是递归

通常我们写出很多函数之后,这些函数是用来提供给其他地方调用完成一些事情的。比如我们有函数gcd用来计算两个数的最小公约数。如果我们要计算三个数的最小公约数呢?我们可以写一个新的函数gcd2,假设三个数为a,b,c,可以调用gcd(a,b)得到a和b的最小公约数ab,再调用gcd(ab,c)得到三者的最小公约数。这种函数之间的调用是很常见的一种情况,也是模块化编程的一种体现。而递归就显得比较“奇葩”,并且它的代码也比较难看懂,因为它的特点就是:我调用我自己。

当你看到这样的代码时,你是否会懵逼呢?

int f(int n){
    if(n == 0) return 0; 
    return n + f(n-1);
}

在函数f的里面竟然调用了函数f自己。要怎么理解这个代码呢?其实,代码在执行的时候,我们每调用一个新的函数,都会被记录起来,比如前面的例子,我们是先调用了gcd2,再调用了gcd,这个顺序其实系统是会帮我们记录保存在一个“栈”里面。当我们的主程序调用f(4)的时候会发生以下的情况:

一开始调用f(4)的时候,要返回给主程序的是 4 + f(3) ,但此时f(3)的值未知,需要继续调用f(3),f(3)要返回给f(4)的返回值是 3 + f(2),f(2)又不知道,继续调用f(2)。同样,f(2)返回 2 + f(1), f(1)返回 1 + f(0)。到了f(0)的时候,n == 0 的判断条件终于为真了,直接返回 0。f(1)收到了 f(0)的值后,计算完1+0后把结果交回给f(2),f(2)又计算完结果之后交给f(3),f(3)计算之后给f(4),f(4)计算出最终结果给我们的主程序。我们可以发现最终这个程序完成工作是“计算1加到n的和”。像这样一层一层的调用自身,其实就是递归,而代码中对n是否为0的判断,也叫做递归边界,使得递归能够及时停止。想一下,如果没有递归边界,在调用完f(0)之后,还会继续调用f(-1),f(-2),f(-3),并且永远不会停止,这个时候,由于系统保存调用层次信息的“栈”是有容量限制的,无限递归最终必定会导致“栈溢出”,也就是到达了系统能够存储的极限了,程序会报错退出。

2. 裴波那契数列

image

在计算机中有一个经典的斐波那契数列,数列的前两个数为1和1,之后每个数都是前两个数之和。现在要我们求出第10个裴波那契数。我们可以拿纸算一算就出来了,比如我现在直接在大脑里算出前10个为:1,1,2,3,5,8,13,21,34,55,因此第10个数就是55。然而,求第10个数这个问题也可以用递归来实现。要知道第10个数,我们首先要知道第8和第9个数,要知道第8个数,需要知道第6和第7个数……就这样一直往前反推,初始条件反而变成了退出条件。并且,为了能够反推,计算机利用一种称为“栈”的数据结构来存储递归过程中产生的数据。现在让你在大脑里模拟递归的过程,先是f(10),再是f(8)和f(9),要求f(8)需要f(6)和f(7),要求f(6)需要f(4)和f(5)……是不是多来几层你就晕了?这也是我们比较难以理解递归的一个原因,因为我们没办法完全模拟出递归中反推的过程。"递归的实现"难以理解,尤其是利用计算机语言实现递归。因为,实现是反过来的,不是让你从初始条件推,而是反过来一直推到初始条件,初始条件反而变成了退出条件。

初学者需要了解好递归这个概念,利用递归我们能够写出许多优雅的代码,但是像“计算1加到n的和”,或者是“计算裴波那契数列”这样的问题,完全可以用for循环写,甚至直接用公式就实现,速度反而会更快,毕竟系统帮我们保存调用过程的信息也需要时间和空间。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容