什么是递归?先了解什么是递归.

欢迎阅读我的个人博客,有更好的排版和文章:https://pushyzheng.com/posts/recursion/

1. 介绍

一说起递归,我想每个人都不陌生。举个从小就听过的例子:从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山...

还有你从两面相对的镜子中看到的画面,其实都是抽象出来的递归现象,但是严格来说并不是递归,因为会一直重复下去,没有终止条件,那就称为死循环了。有关递归和死循环的异同我们之后会说到,那么现在先来了解一下什么是递归?

那么什么是递归呢? 要理解递归,就得先了解什么是递归,实际上这句话就是一个递归。这么说可能不好理解,接下来我举个简单的例子来解释这段话的意义。

假设我们现在都不知道什么是递归,我们自然想到打开浏览器:输入到谷歌的网页,点击搜索递归,然后在为维基百科中了解到了递归的基本定义。在了解到了递归实际上是和栈有关的时候,你又蒙圈了,什么是栈呢?数据结构没学清楚,此时的你只能又打开谷歌,搜索什么是栈。接下来你依次了解了内存/操作系统。在你基本了解好知识之后,你通过操作系统了解了内存,通过内存了解了栈,通过栈了解了什么是递归这下你恍然大悟!原来这就是递归啊!

这下应该有点明白了吧,这个过程其实就是递归的过程,如果不了解递归,那就先了解什么是递归,可能你会说这是个循环并不是递归,我们前面说到,递归是需要终止条件的,那么你明白递归是什么其实就是终止条件。整个过程,搜索引擎充当递归函数(只是形象的假设)。在你去依次查找递归/栈/内存/操作系统的过程为前行阶段,在你都了解完之后,反回去了解含义的过程为退回阶段。如果还是不太清楚,可以接着看下面的例子。

2. 示例

也许之前你在网络上看到过这张图片:

实际上这张图就很形象地表达出了递归,这句吓得我抱起了抱着抱着抱着我的小鲤鱼的我的我的我如果从字面意义上看可能看不出是什么意思,那么我们可以通过代码来实现同样的效果:

function Recursion(depth) { console.log('抱着'); if (!depth) { console.log('我的小鲤鱼') } else { Recursion(--depth); // 递归调用 } console.log('的我'); } console.log('吓得我抱起了'); Recursion(2)

在终端的打印结果为如下,可以看到和上面的那段话是一样的:

代码其实十分简单,但是需要理解的是:if代码块的条件(!depth)为递归调用的终止条件,在else代码块内递归调用函数.我们前面有说到递归的过程是存在前行和退回阶段的,那么在前行阶段我们在每次调用函数后,打印出了'抱着',并且当depth≠0时重新调用该函数;在退回阶段,将会去执行代码console.log('的我');再打印出'的我'.

褚跃跃的图也能比较清楚地反映出这个过程:

好了!这下你应该明白什么是递归了吧?如果你还没有明白什么是递归的话,你可以看什么是递归?

3. 应用

3.1 斐波拉契数列

有关递归应用的应用有很多,例如注明的斐波拉契数列就可以通过递归来实现:

def fib(x):
    if x < 2:
        return 0 if x == 0 else 1
    # 当x > 2时,开始递归调用fib()函数:
    return fib(x - 1)   fib(x - 2)

print(fib(6))  # 打印结果为:8

这里需要对i<2时的特殊情况做出判断,当x==0时,直接返回0,当x==1时,直接返回1

3.2 遍历文件

首先我们需要了解遍历的算法:定义的file_display函数以某个目录(/home/pushy)作为遍历的起点.遇到一个子目录时,就先接着遍历子目录(递归调用函数)。遇到一个文件时,就直接对改文件进行操作(这里只打印出文件的文件名):

import os def file_display(filepath): for each in os.listdir(filepath): # 得到文件的绝对路径: absolute_path = os.path.join(filepath, each) # 得到是否为文件还是目录的布尔值: is_file = os.path.isfile(absolute_path) if is_file: # 当前的绝对路径为文件: print(each) else: # 当前的绝对路径为目录: file_display(absolute_path) file_display('/home/pushy')

这样我们就可以遍历到/home/pushy路径下的所有文件:

另外我们还可以使用递归来创建目录:

import os

def createFile(dirname):
    exits = os.path.exists(dirname)
    if exits:
        return True
    else:
        # 开始递归调用函数,并接受其返回值:
        rec_result = createFile(os.path.dirname(dirname))
        if rec_result:
            # 如果不存在该目录,则创建dirname的目录,并返回已经创建(存在)的值True:
            os.mkdir(dirname)
            return True

createFile('./aa/bb/cc')

4. 循环与递归

好了,递归的知识差不多介绍完了。如果看完上边大概已经了解了循环和递归的区别了。对了!简单来说,循环是有去无回,而递归则是有去有回(因为存在终止条件)。

举个栗子,你用你手中的钥匙打开一扇门,结果去发现前方还有一扇门,紧接着你又用钥匙打开了这扇门,然后你又看到一扇们...但是当你开到某扇门时,发现前方是一堵墙无路可走了,你选择原路返回——这就是递归

但是如果你打开一扇门后,同样发现前方也有一扇们,紧接着你又打开下一扇门...直到打开最后一扇门出去,或者一直没有碰到尽头 (死循环)——这就是循环。

参考资料:

[知乎]什么是递归

七天学会NodeJs--递归算法

(0)

相关推荐

  • python笔记4-遍历文件夹目录os.walk()

    前言 如何遍历查找出某个文件夹内所有的子文件呢?并且找出某个后缀的所有文件 一.walk功能简介 1.os.walk() 方法用于通过在目录树种游走输出在目录中的文件名,向上或者向下. 2.walk( ...

  • 创建级联目录的五种方法

    创建级联目录的五种方法 方法一:迭代方法 <?php function mk_dir($path){ //当前目录存在,直接结束该函数. if(is_dir($path)){ return tr ...

  • 第26天:Python os 模块详解

    第26天:Python os 模块详解

  • JS数据结构与算法学习笔记大全 (温故而知新,可以为师矣。)

    目录: 6.1 概念 6.2 树的存储结构 6.3 二叉树 6.4 二叉搜索树 5.1概念 5.2 js实现一个简单哈希表: 5.3 处理冲突 4.3.1 原型链实现继承: 4.1 概念 4.2 js ...

  • 开眼界!Python 遍历文件可以这样做!

    来源:Python 技术「ID: pythonall」 Python 对于文件夹或者文件的遍历一般有两种操作方法,一种是至二级利用其封装好的 walk 方法操作: import os for root ...

  • Python|利用递归轻松解决数的乘方问题

    问题描述求一个数的乘方,数学公式如下是成立的示例: 我们可以将乘方的运算转换为乘法的运算输入: ,定义 ,b=y/2输出: 解决方案求x的y次方的值,当y是偶数时,最后能转换成两个数相乘,当y是奇数时 ...

  • 方法重载与可变参数与递归

    举例说明: //方法有修饰符,返回值类型,方法名,参数类型,参数名public static int name(int a,int b){//这里是形参,主方法内调用并给真实传递的才是实参 //方法体 ...

  • 递归与区间套

    复盘  今日大盘缩量调整,成交6900亿.海南板块暴涨,医美网红概念活跃,龙头大白马下跌.大盘萎靡不振,个股炒作情绪却极其高涨,冰火两重天!新股午盘全部临停,N中金福盘中飙涨10倍,N共同7倍.可惜本 ...

  • Java递归

    递归就是:A方法调用A方法,自己调用自己 能不用就不用,只适合一下小的计算 1 @Test 2 public void test() { 3 Recursion recursion = new Rec ...

  • 图解一导再导三导,轮番轰炸找快感,层层递归有收获

    图解一导再导三导,轮番轰炸找快感,层层递归有收获     导函数是研究函数单调性.极值点.零点等性质的"利器",求导后主要判断导函数的正负.但是往往一次求导后无法得到理想的表达式, ...

  • Perl篇:递归遍历及拷贝文件共享服务器中目录

    关于Perl递归遍历目录的文章其实很多,但是大多数都是针对本地机器磁盘间的操作,如将C盘根目录下的A文件夹整个拷贝到D盘根目录下的A文件夹.但是,对于将一个局域网内其他机器开放的文件共享目录递归遍历或 ...

  • 灵素之问 | 伤寒论六要素递归是对张仲景的礼赞

    灵素之问 | 伤寒论六要素递归是对张仲景的礼赞 原创 忆忘 腔调中医 今天 收录于话题 #灵素之问 120个 灵素之问 还原古人观察视角和中医经验理法的演进. 栏主 忆忘先生,从事临床工作,研习传统文 ...

  • 缠中说禅:分解与递归

    分解与递归 一.分解 分解,是指将一个完整的走势按一定的级别,分解成连续的且相对独立笔(严格笔)或段(线段)的连接:或将某一严格笔分解成次级的走势类型.它分为同级别分解和非同级别分解两种. 1.同级别 ...

  • 学会了没有?书上级别递归原理图 看懂没有?

    来自:MACD论坛(bbs.macd.cn)作者:天九地七 地板 楼主| 发表于 2019-12-22 18:57 | 所以,知道缠论级别大小几乎无任何意义!只需知道在攻击中,还是在不攻击中(即中枢震 ...