adinxu
by adinxu
~1 分钟 阅读用时

分类

标签

斐波那契数列与汉诺塔问题及递归

额,人比较笨,从基础的来

斐波那契数列

已知初始有一只小兔子,已知小兔一个月后变为成兔,成兔一个月可产崽一只,问第n个月时兔子的总数量。
由最开始的条件分析可知,这个月成兔,就是上个月总的兔子数量,而小兔就是上上个月总兔子数量,则f(n)=f(n-1)+f(n-2),此处f(n)是兔子总数。

汉诺塔问题

有三个柱子,A,B,C,其中A上套着一摞圆盘,圆盘大小不同,从上到下圆盘依次增大,限制是,每次只能移动一个圆盘,每次放下圆盘时,必须大得在下,小的在上。每次只能从最上面取圆盘。A,B,C都可以放圆盘。问,把A上的圆盘全部移到C,最少需要多少次数。
刚开始没想出来,后来想到,在转移过程中一定有这么一步,那就是移动最大圆盘到C的时候,此时,A上只剩最大圆盘,B上有剩下的所有圆盘,C是空的,有且仅有这种情况,才能够转移最大的圆盘。那么移动次数就是把这个最大的挪过去的一次+剩下那一摞移动两次–移到B再移到C。三个步骤,假如有10000个圆盘,第一步,把9999个移到B,然后把最大的移到C,然后把9999个移到C,注意,移动9999个不是一步完成的。而移动9999个圆盘,就是移动9998个圆盘的事了。
对,又是一个递归,最少次数f(n)=2f(n-1)+1,其中f(1)=1.

递归、迭代、尾调用

上面两个问题都推倒出了每一步和前面步骤的数量关系,可以使用递归求解,停止条件就是初始条件,如在斐波那契数列中,初始条件就为f(1)=1,f(2)=1.在汉诺塔问题中,f(1)=1.
递归虽然逻辑清晰,好编码,但是因为需要层层调用,对堆栈的需求较高,并且存在冗余计算问题。
迭代是另外一种计算方法。关于迭代和递归的区别以及尾递归,可以看这个。尾递归可以看这个
简单说,迭代就是,这次的输出是下次的输入。而递归则是,本次的输入依赖下次的输出。这个也可以作为参考。

循环和递归有种逆向思维关系, 循环通常来自底向上, 递归自顶向下。 他们之间可以转化。