戏说(细说)递归

------------------------------------------------------------
author:hjjdebug
date: 2017年 12月 29日 星期五
------------------------------------------------------------
网上谈递归内容不少,但不和我口味,所以自己也聊一聊递归
刚过圣诞节,就从圣诞老人的礼物聊起.
1. 圣诞老人的礼物!
每年圣诞节圣诞老人都给孩子们发放礼物,礼物有三种,糖果,巧克力和蛋糕.
你家孩子收到了一包礼物,打开一看,是2颗糖果,3颗巧克力和1块蛋糕但还有一个小一点
的包裹,你又打开了这个包裹,是2颗糖果,2可巧克力,2块蛋糕,但还有一个更小一点的包裹,
你很好奇,想知道圣诞老人到底送了多少礼物,于是又打开了这个包裹....
这就是一个甜蜜的递归故事.

你要想知道结果,一定要不停的打开包裹,直到最小的包裹被打开.
你可能要说了,圣诞老人搞什么名堂,它把礼品放到一个包裹了多好?
哦,这是别的问题.圣诞老人要给每个小孩发礼物,所以有n个小孩,就包了n个小包裹
你家孩子体育好,老人又加了2块糖,但是包上的包裹就不要打开了,用个较大的包裹包上小包裹和糖就好了.
圣诞老人做完了,继续查,一看,你家孩子智育好,又要奖励2块蛋糕,再用一个较大的包裹报所有礼品包好,
再查,你家孩子德育也好,再奖励几块巧克力,用包裹包起来.圣诞老人一年没干别的事,专门跟那么多小孩
包食品啦! 感谢圣诞老人的辛勤劳动!

2.  能不能不提圣诞老人,说个现实生活中存在的例子.
嗯,好!
19大召开,中央精神开始传达到省里学习,省委书记,省长一起到场. 过不长时间,中央精神又下达到县里,
县委书记,县长到场,再继续,传达到乡里,乡长,乡党委干部集体学习... 这就是递归.

3. 别扯的太大, 我们常见的示例有没有?
有. 你玩电脑吗?
嗯,当然.
那你打开一个文件夹,发现里面有不少文件,但还有几个文件夹, 你再打开里面的文件夹,发现又有几个文件,
几个文件夹,你又打开文件夹.... 目录(文件夹)和文件的这种关系,就是一个典型的递归.

4.我是编程序的,能不能来点更实际的呢?
能! 好比说你收到了一个压缩文件叫a.zip 吧,解开来一看,有几个文件,但还有一个b.zip, 你把b.zip 解开,
有几个文件,但还包含了一个c.zip, 你把c.zip 解开,发现...... 这又是一个典型递归.

我观看了一颗树,树干长出粗树枝,粗树枝又长出细树枝,细数枝又长出更细的树枝,最后长出的是叶子,这不
就是递归问题吗?

因为数据是嵌套的,所以程序是递归的.
道曰:其大无外,其小无内.我们看看道家的商标太极图,一个圆圈里包含了两个阴阳鱼,两个阴阳鱼的鱼眼是个圆圈,
圆圈里又是两个阴阳鱼,环环相套,其大无外,其小无内.假如你就在这个阴阳鱼内,你知道你在第几层吗?
哈哈! 这不就是递归的间接调用吗.圆圈不直接调用圆圈,通过阴阳鱼的眼睛调用圆圈!
我又想起了电影盗梦空间,梦里套梦,不知道自己到底在哪层梦里还是在现实里.
好了,现在我们知道了,原来是因为数据是嵌套的,所以我们可以用递归的方法来实现.
真实的递归,不能是无穷的,而应该是有穷的,有退出条件.如果永远都不退出, 那我们还等它干什么!

递归告诉我们,不需要处理每一个数据,你只要告诉我从这一层到下一层的方法就可以了, 至于下一层到下下一层,
你就不用操心啦,照搬现在的方法就可以了. 中央精神,中央常委把它传达的省里就可以了,至于从省里传达到县里,
让他们自己照搬就可以了,否则全部亲历亲为还不把中央常委累死.

递归程序与递归思维
所以,我们要计算10!, 只要计算10*9!就可以了, 那9!谁告诉我呢?
要计算斐波那契数F(15), 只要计算F(14),F(13)然后两者相加就可以了,那谁告诉我们F(14),F(13) ?
现在传达中央精神,你是省长,你只要传达到县长就可以了,那谁传给乡长呢?
这些看似是问题,其实又不是问题,关键是要写一个递推公式. 这个公式就是实现怎样从这一层向下一层转换.
9!你不知,但8!你知道吧? 8!也不知,那7!,6!,.....1!, 1!=1,2!=2, 好,这就够了,这就是退出条件了.
F(14),F(13)不知, 但逐级递减,,,, F(1)=1,F(2)=1, 这就够了!
汉诺塔问题,要移动n个盘子,先让别人移动n-1个盘子,自己移动一个盘子,再让别人移动n-1个盘子. 你可能要问,
别人怎么移动n-1个盘子?
嗯, 它只要调用递推公式,然别人先移动n-2个盘子,它再移动一个盘子,再让别人移动n-2个盘子就可以了.
那n-2个盘子怎么移动呢? 以此类推了.... 只剩下一个 盘子了,一个盘子从from,到to直接拿过去就可以了.
有句话说得好啊,
大懒使小懒,小懒使门槛,门槛使土地,土地老头坐起喊.
这就是递归的思想!

关于汉诺塔的思考.
调试代码理解以下问题!
1.它总共移动了多少步.
它的移动次数增长是非常迅速的,按指数增长, 因为次数C(n)=2*C(n-1) + 1,
可以证明, 这个C(n)=2^n-1, 用数学归纳法可以证明
C(1) = 1
假设 C(n)=2^n-1 成立
则 C(n+1)= 2*C(n)+1 = 2*(2^n-1)+1 = 2^(n+1)-1.
公式得证.
2.对于一个层高8层汉诺塔递归算法
从递归深度考虑,假若开始glevel=0, hano(8) 为第一层调用,
hano(7)为第2层调用,则hano(1)为第8层调用,其调用次数.
hano(8)->1  移动了1个盘子 , 一级领导搬最大的盘子
hano(7)->2     移动了2个盘子 , 二级领导搬次大的盘子
hano(6)->4    移动了4个盘子 , 三级领导搬三大的盘子.
hano(5)->8    移动了8个盘子 ,  .....
hano(4)->16    移动了16个盘子 , ....
hano(3)->32    移动了32个盘子 ,  ....
hano(2)->64    移动了64个盘子 , ...
hano(1)->128 移动了128个盘子, 人民群众挪最小的盘子, 搬的次数最多.
总共移动了255次盘子.
分级管理,乃管理之道,
大领导只要移动一次大盘子就可以了,剩下的由小领导和人民群众去移动.
好了,我对汉诺塔的移动全貌有了了解,要想知道目前调用层次在那里,看看谁在移动盘子就知道了.
当然,大多数情况下你会看到人民群众在干活,因为他们占了一半时间在搬盘子.
汉诺塔问题理解还有困难吗? 有困难和我联系!

递归的分级思想启示我们,当你遇到问题时,一定要想办法把事情化小,
大事化小,小事化了,解决问题!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值