递归理解

  • 什么是递归?

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],等等。用递归来解决这些问题,往往几行代码就搞定了一些看起来相当”吓人“的问题。 当然,递归的性能问题是另一回事,栈的分配,函数调用代价都是在具体工程实践中要考虑的。 但现在只是讨论递归思想的话,不妨先放下那些,欣赏下递归的美。

[1]:http://en.wikipedia.org/wiki/Recursion
[2]:http://zh.wikipedia.org/zh/%E9%80%92%E5%BD%92
[3]:http://www.nowamagic.net/librarys/veda/detail/2314
[4]:http://en.wikipedia.org/wiki/Tree_(data_structure)
[5]:http://tenaciousc.com/?p=1000
[6]:http://www.sparknotes.com/cs/recursion/whatisrecursion/section1.rhtml

古之欲明明德于天下者,先治其国;欲治其国者,先齐其家;欲齐其家者,先修其身;欲修其身者,先正其心;欲正其心者,先诚其意;欲诚其意者,先致其知,致知在格物。物格而后知至,知至而后意诚,意诚而后心正,心正而后身修,身修而后家齐,家齐而后国治,国治而后天下平。

这是一个调用自身的过程,我们把”明德于天下“当作函数本身来理解,每一层调用的参数依次是治国、齐家、修身、正心、诚意、致知、格物。最后在”格物“触发返回条件。

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

转自:https://www.zhihu.com/question/20507130

时间: 2024-10-04 21:02:53

递归理解的相关文章

day16【Pyhton 递归】递归理解

函数的产生可以使代码可以重复使用. 递归的产生可以 使函数重复使用自己,但是python默认递归的深度为1000,这个深度是可以修改的. 自己理解:递归虽然可以重复使用但是,需要设置一个条件,这个条件就是使递归跳出循环的. def age(n): if n == 1: return 40 return age(n-1)+2 递归进行二分查找: def find(lst,aim): #这种算法可以在查找的值存在的情况下,不会报错,但是在,查找不 存在的值时,就会报错. mid = len(lst)

java基础之IO流及递归理解

一.IO流(简单理解是input/output流,数据流内存到磁盘或者从磁盘到内存等) 二.File类(就是操作文件和文件夹的) 1.FIleFile类构造方法 注意:通过构造方法创建的file对象是在内存里面,而不是在磁盘里面. File(String pathname)  根据指定的路径名创建file对象 File(String parent, String child)  根据 parent 路径名字和 child 路径名创建一个File对象 File(File parent, Strin

递归理解-汉诺塔问题

汉诺塔问题 汉诺塔问题的求解可以巧妙利用递归思想 以下摘自知乎上我认为阐述得很清除回答: 要用程序来解决这个问题,我们先定义一个移动函数:move(移动数,开始柱,中转柱,目标柱), 例如 move(2,A,B,C) 表示将2个盘子从A柱(开始柱)借助B柱(中转柱)移动到C柱(目标柱). 关于开始柱,中转柱,目标柱这三个概念可以用移动过程中的某个状态来理解, 看下面一张图应该就能明白: 有三种状态的柱子,开始柱,中间柱,目标住,开始柱指的是开始状态时存放所有盘子的柱子,中转柱指的是中间状态时暂时

算法交作业之循环和递归(二)

说明: 循环是学习编程过程中的不可或缺的一部分.同时递归同循环有着千丝万缕的关系. 求和函数示例: //求0到n的和.求和失败返回-1.否则返回结果. #include <iostream> //最常见的循环写法. long long Sum(unsigned int&& n){ long long sum = 0; for (unsigned index = 1; index <n+1; ++index) sum += index; return sum; } //递归

HDU 2064 汉诺塔III(递归)

题目链接 Problem Description 约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下.由小到大顺序串着由64个圆盘构成的塔.目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面.现在我们改变游戏的玩法,不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到下盘的上面.Daisy已经做过原来的汉诺塔问题和汉诺塔II,但碰到这个问题时,她想了很久都不能解决,现在

重踏学习Java路上_Day20(递归,IO流)

1:递归(理解)     (1)方法定义中调用方法本身的现象        举例:老和尚给小和尚讲故事,我们学编程    (2)递归的注意事项:        A:要有出口,否则就是死递归        B:次数不能过多,否则内存溢出        C:构造方法不能递归使用    (3)递归的案例:        A:递归求阶乘        B:兔子问题        C:递归输出指定目录下所有指定后缀名的文件绝对路径        D:递归删除带内容的目录(小心使用) 2:IO流(掌握)  

[原创] 算法之递归(1)

算法之递归(1) 最近事情太多了,很少有时间可以完全静下来认真研究一些东西:每当专注的写代码的时候,总是被其他事情打断.还好,礼拜天来了,总算可以抽出一些时间了J <代码之美>第一章有一个关于模式匹配的问题,即根据正则表达式在相应的文本中找到匹配的值,找到返回1,没找到返回0.撇开具体的实现,里面优美的递归调用倒是深深地吸引了我.于是,我开始重新思考递归,毕竟有些细节之前的思考还不够到位. 什么是递归 我的印象中的递归是函数调用自身来完成预先定义的操作.当然,实际涉及的内容更多,比如退出递归的

递归、字节流、文件复制_DAY20

1:递归(理解) (1)方法定义中调用方法本身的现象. (2)递归注意事项: A:要有出口,否则就是死递归. B:次数不能太多,否则内存溢出. 特殊事项:构造方法不能递归定义. 例子:cn.itcast.demo package cn.itcast; /* * 递归算法: * 自己调用自己. * 方法内定义:调用到什么程度,就不调用自己了.即递归出口. */ public class Demo { public static void main(String[] args) { method(5

一、javaSE (二十)递归、IO流、自学字符流

1:递归(理解) (1)方法定义中调用方法本身的现象 举例;老和尚給小和尚讲故事,我们学编程 (2)递归的注意事项; A:要有出口,否则就是死递归 B:次数不能过多,否则内存溢出 C:构造方法不能递归使用 (3)递归的案例 A:递归求阶乘 B:兔子问题 C:递归输出指定目录下所有指定后缀名的文件绝对路径 D:递归删除带内容的目录(小心使用) 2:IO流(掌握) (1);O用于在设备间进行数据传输的操作 (2)分类 A:流向 输入流     读取数据 输出流     写出数据 B:数据类型 字节流