递归算法中递是"去"的意思, 归是"回"的意思, 整个递归就是"有去有回"的过程.
什么样的问题要用递归来解决? 一句话: 对于问题N,如果N-1已经解决了,那么N是否很容易解决。
学递归调用要明确以下三点:
1、整个递归的终止条件是什么?
2、应该返回给上一级的的返回值是什么?
3、一级递归要做什么?(重复逻辑)
其实2可以和3合并:
1. 递归终止条件
2. 把问题规模缩小
启发的例子:
下楼拿快递就是个递归过程 :
你在床上葛优躺, 快递到了, 但要自己去自提柜拿, 你依次打开卧室门, 屋门 , 楼门, 快递柜门, 拿到了心仪的快递.(这是"递过程", 没错是快递的递)
取到快递, 你先打开楼门, 再打开屋门, 再打开卧室门, 最后再次回到床上葛优躺. (这是"归过程")
神奇的取快递, 竟然神不知鬼不觉的完成了一次递归算法.
这里面思考下递归三要素:
1、整个递归的终止条件是什么? ----当然是拿到快递(剩下的就是返回卧室)
2、应该返回给上一级的的返回值是什么? ----取快递的状态: 归的过程才会有返回值, 返回值是快递包裹以否已经通过了这一级的门.
3、本级递归要做什么? ----开门
“递过程”是指:递归问题必须可以分解为若干个规模较小,与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决,就像上面例子中的开门一样;
“归过程”是指 : 这些问题的演化过程是一个从大到小,由近及远的过程,并且会有一个明确的终点(临界点, 如打开快递柜, 拿到快递),一旦到达了这个临界点,就不用再往更小、更远的地方走下去。最后,从这个临界点开始,原路返回到原点,原问题解决。
大象放冰箱:
回到正题,我们的是讲大象的, 准确的说是讲汉诺塔的. 汉诺塔游戏是把最左边(from)的一堆饼, 堆到最右边的杆子(to)上,中间那个杆子叫做(buffer).
图1 汉诺塔
图2 大象放冰箱?
图3.1 把冰箱门打开
图3.2 把大象放进来
图3.3 把冰箱门关上
其中冰箱门代表的大饼数量n可以是0 - N之间任意一个数. 当n=0时, 便成了最简单的情况.
def move(n,begin,buffer,to):
if n==1:
print('Move',n,'Begin',begin,'to',to)# 终止迭代条件
else:
move(n-1,begin,to,buffer) #将n-1个圆盘从a柱搬到b柱 ,第一步,打开冰箱门
move(1,begin,buffer,to)#将最大的圆盘从a搬到c,第二步,把大象放进去
move(n-1,buffer,begin,to)#将搬到b的n-1个盘子搬到c,第三步,冰箱门带上
汉诺塔是递归过程调用了三次自己, 相比一般的递归更加复杂.
对递归的理解的要点主要在于放弃!
放弃你对于理解和跟踪递归全程的企图,只理解递归两层之间的交接,以及递归终结的条件。
https://www.cnblogs.com/mhg215/p/9729479.html
https://blog.youkuaiyun.com/wxystyle/article/details/80174799
https://www.zhihu.com/question/24385418