动画:这一次用动画搞懂递归!

递归这玩意儿,尤其是对于初学者,在数据结构和算法中归为“玄学”一类。咳咳,如果今天鹿哥能把这玄学的玩意儿讲明白,岂不是要上天。同样讲不明白的后果,鹿哥将会被后台的石锤大队石锤…

在这里插入图片描述

其实不学递归也没啥,但是学到后边会发现,什么 0-1 背包问题(动态规划内容,也可以用递归解决)、深度广度优先遍历、八皇后问题,回溯算法等,反正各种内容都会涉及到递归。所以,今天放句狠话,必须搞它,搞的它明明白白的。

在这里插入图片描述

(此篇调动全身的细胞去讲明白递归,虽然看起来很简单,但是给一个没有接触过递归的人讲懂很难)


什么是递归

对于玄学,绝不能用正常思维去搞它,那绝对是搞不它的。既然是玄学,那我们就采用玄学思维去理解和分析递归。

为啥叫它玄学?不是有多难,而是有些人,一看就明白,一用就是精髓。而有些人呢,比如我,一开始咋看咋觉得这东西就像是“黑洞”,递进去,就归不出来了。

在这里插入图片描述

划重点,递归,必须有递有归才叫递归。为了能够形象的代表一下,先了解一下递归的操作,小二,上动画。

在这里插入图片描述

从一个简单问题入手

要想搞懂递归,不能直接上手复杂的递归问题,而是先从一个简单的问题入手。

我们就拿排队打饭的例子,如果鹿哥要去餐厅,人太多,不得不去排队,但是此时我想知道自己是队伍中第几个,由于队伍太长,我看不到队伍的第一个人,自然而然没法一个个的数。

那么玄学递归排上用场了,我会让我前边的人依次问自己是当前第几个人,然后依次类推,直到问到第一个人,那么这个过程是“递”的过程。

在这里插入图片描述

第一个人不耐烦吼了一声,你眼X啊,没看到我是第一个人,正在打饭吗?

这个人吼了一声,这个就是所谓的终止条件,也就是递的终点。

在这里插入图片描述

此时,鹿哥肚子咕咕的叫了两声,当然,我现在还不知道自己是队伍第几个。此时队伍中的第二个人知道位置了,然后告诉第三个人,第三个人告诉第四个人…

在这里插入图片描述

最后,我前一个人告诉他目前在队伍中是第几个,那么鹿哥就知道自己此时的位置。很容易理解,这个过程就是“归”的过程。


遇到的问题

由此看来,鹿哥的道德素质没的说,从来不插队,而且还能理解递归,一个字“骚”,两个字“真骚”。

在这里插入图片描述

这时候有人要说了,这个过程俺早就理解了,但是对于有些递归问题和代码,脑子里总是想不明白层层嵌套的过程,而且总是想着想着就递进去,归不出来了,哎,我这脑子,是不是很笨呢。

鹿哥告诉大家,其实不用担心,凡事都要有个过程,要有个思想转化的过程,要用心去感受,感受它的抚摸,感受它带给你的快感。

这时候,很多人的告诉你的解决办法是,不要去想这个过程,要去寻找终止条件和递推公式,然后按照套路写出代码。

嗯~ 对~,鹿哥认为上边确实说的没错,但是这类玄学玩家并没有搞明白为什么初学者往往去想这个过程,进入这个过程圈套呢?

鹿哥想了一想,结合自己学习递归的经验,越是想不明白,就越想弄明白递归过程,这不叫刨根问底,这叫“骚气风发”。

假如我们搞明白一次递归的整个过程,那么以后遇到其他的递归就无需去想这个过程了,因为其他的递归几乎一样的套路,我们心理上接受之后,假装自己知道了所有的递归过程,以后再遇递归,不再去想这个过程,而是直接按照公式套用不就 OK 了吗?

鹿哥,你说起来容易,你能用什么方法让我们这些刚接触过递归的人明白这个递归过程。其实这件事困扰了鹿哥好久,作为一个为被称为写文风骚,动画风骚的鹿哥,今天斗胆尝试一下,看懂了就给我疯狂在底部点赞,把鹿哥按到地上摩擦,这才能凸显出鹿哥的 Sao 气。


用动画理解递归

继续拿排队那个例子,我们已经知道了终止条件和层与层之间的关系。

终止条件为:f(1) = 1,也就是第一个人知道自己的位置的。然后层与层之间的关系为 + 1 的关系,也就是说求第 n 个人在队伍中的位置 f(n),那么就问一下前一个人,也就是 n-1 在队伍当中的位置 f(n-1) 加上 1,也就是 f(n-1) + 1。

有点绕口,咱们看完整的实现代码:

在这里插入图片描述

如果你还是有点懵逼的话,还是不能理解整个程序的运作,小二,上图解和动画。

在这里插入图片描述
上边的动画是我们人脑的理解,而下边的动画才是程序真正的调用过程。

每个颜色的方块代表的是该每一层递归的函数,而程序是自上而下执行滴,也就是下边这种形式。

在这里插入图片描述

如果你理解函数的执行过程就是入栈过程的话,其实递归就是不断入栈的过程,然后最里层的函数执行完毕,然后函数依次出栈。

如果你寥寥草草的阅读完毕,并没有感觉看懂递归过程,这可真不怪你们鹿哥了,你鹿哥已经尽力用动画去还原程序递归过程和大脑的递归过程了。


光说不练假把式

如果上边你能够吃透,那么下面的那些题型以及以后的文章所提到的各种有关递归的过程,真的不在话下。有时候只是换了一个角度理解,换了一个角度理解,换了一个角度理解,鹿哥重要的 Sao 话说三遍。

再来一个叫什么斐波那契数列的那家伙,杠杠滴。找规律 0、1、1、2、3、5、8、13、21… 没错,除了第一第二个,剩余的数据都是前两个数据之和,那么求第 n 个数据是多少?

其实这个问题对你来说已经小 K 死了,就是换了个模样,前两个数不就是换了一个问法,也就是上边排队的时候,鹿哥前边两个人嘛?一个叫 n-1 一个叫 n-2,终止条件变成两个窗口,同时给第一个人和第二个人打饭,也就是 f(1) = 0,f(2) = 1。

直接出结果,代码如下:

在这里插入图片描述

我会变形,专门误导你

其实相同的递归公式确有不同的理解方式,这你敢信?难道这就是递归归为玄学的地方,不信你看,下面说来就来了。

一个蛤蟆二条腿,两只蛤蟆四条腿 三只…,不对,应该是蛤蟆一次可能跳上一个台阶,也有可能一次跳两个台阶,那么 n 个台阶,有几种跳跃方式呢?

这个咋就和上边排队不一样了呢?嗯,不知道如何理解和下手。

其实这个数蛤蟆腿,不对,这个蛤蟆跳台阶的问题只不过换了一种思考方式,我们来看这种思想是如何绕晕我们的。

一个台阶,只存在一种可能,那就是让蛤蟆跳一次。二个台阶,有两种可能,那就是让蛤蟆一次只跳一个台阶,或者一次性挑两个台阶。那么三个台阶,你自己数数去吧,我就不啰嗦了。

那么 n 个台阶有几次可能,这样一个个数太费劲,我们换种思想,也就是递归的思想。我们将蛤蟆跳台阶分为 m 次跳上去。第一次跳,有两种方式,那就是要么一次性跳一个台阶,剩余的 n-1 个台阶我先不管。或者第一次跳两个台阶,剩余的 n-2 个台阶我暂时不管。

如果 f(n) = m,也就是当前有多少次跳法。我想把上边的两种相加,剩余的暂时先不管,也就是 f(n) = f(n-1) + f(n-2)。

那么神奇的一刻就要来了,n 个台阶,我决定了第一次只跳一个台阶之后,那剩余 n-1 个台阶的每个台阶就会面临同样的选择。如果我决定了第一次只跳 2 个台阶之后,那么剩余的 n-2 个台阶的每个台阶也会面临同样的选择。

蛤蟆的的第一次就这样交在鹿哥手中,要么你第一次跳一个,要么跳两个,想一步登天吃天鹅肉,没门。剩余的 f(n-1) 和 f(n-2) 面临同样的选择呀。

只要把 f(n - 1) + f(n - 2) 相加,就是 n 个台阶有几种跳法了。我知道,大部分初学者还是不理解这个思想,图解来一波。

在这里插入图片描述

思考总结

你会发现蛤蟆跳台阶的问题,得出来的递推公式竟然和斐波那契数列的递推公式竟然相同,但是终止条件不同的。

这时你必须像鹿哥一样陷入玄学递归的大思考,同样的一个递推公式,竟然有两种思想,感觉这世界还有这么 TM 神奇的事情,这两者让我陷入了对人生的大思考…

今天的递归基础理解内容就到这里了,后边还会继续分享更复杂的递归,虽然表面上假装让它复杂,但是就是换汤不换药,比如深度广度优先遍历,八皇后问题,回溯算法等,都是和今天分享的八九不离十,最重要的是多去思考和感悟以及总结,这个过程值的你去做。

骚气的鹿哥写文不易啊,不要手下留赞,因为这将决定下一篇你鹿哥输出的动力,点了赞你就是鹿哥的人,鹿哥今后罩着你。

在这里插入图片描述
1、老铁们,关注我的原创微信公众号 「 小鹿动画学编程」,专注于数据结构和算法,网络原理,计算机基础、Web 大前端等,欢迎来鹿哥公众号搞事情。一天一篇动画家属技术搞定你。。

2、给俺点个赞呗,可以让更多的人看到这篇文章,顺便激励下我,就这么脸皮厚!

❤️ 不要忘记留下你学习的脚印 [点赞 + 收藏 + 评论]

文章写了了好几个小时,不妨点赞支持一下。嘻嘻,你不点赞说明你很自私,你怕那么好的文章让别人也看到。开个小小玩笑。

在这里插入图片描述

发布了74 篇原创文章 · 获赞 8512 · 访问量 62万+
App 阅读领勋章
微信扫码 下载APP
阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览