今天学习python的时候做到递归练习题,题目如下:
汉诺塔 (http://baike.baidu.com/view/191666.htm) 的移动也可以看做是递归函数。
我们对柱子编号为a, b, c,将所有圆盘从a移到c可以描述为:
如果a只有一个圆盘,可以直接移动到c;
如果a有N个圆盘,可以看成a有1个圆盘(底盘) + (N-1)个圆盘,首先需要把 (N-1) 个圆盘移动到 b,然后,将 a的最后一个圆盘移动到c,再将b的(N-1)个圆盘移动到c。
请编写一个函数,给定输入 n, a, b, c,打印出移动的步骤:
move(n, a, b, c)
例如,输入 move(2, ‘A’, ‘B’, ‘C’),打印出:
A –> B
A –> C
B –> C
参考答案如下:
def move(n, a, b, c): if n ==1: print a, '-->', c return move(n-1, a, c, b) print a, '-->', c move(n-1, b, a, c) move(4, 'A', 'B', 'C')
我自己推算了一下n = 1,2,3,4的情况,与答案不一致。
首先还是得先知道汉诺塔是什么东西。原来是这种益智玩具。规定:把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘
然后参考了http://www.45fan.com/a/question/56773.html这个帖子,我理了一下思路:
当n=1时,a柱只有一个底盘,直接把这个盘子放到c柱,即A–>C
当n=2时,a柱有两个盘子,先把上面的盘子放到b柱,再把下面的盘子放到c柱,即A–>B,A–>C,B–>C
上面两种情况都很好理解,但是当n=3时,就不能仅仅借助b柱来转移了。因为按照题目要求,b柱也要遵守大圆盘上放小圆盘。
当n=3时,a柱有三个圆盘,我们称它们为大盘,中盘,小盘。先从a柱把小盘放到c柱,再从a柱把中盘放到b柱,再把c柱的小盘放到b柱,再把a柱的大盘放到c柱。此时,a柱上什么也没有,b柱上有中盘和小盘,c柱上有一个大盘。此时,大盘已经成功移动到c柱,之后也不会再操作它,所以可以把它忽略了,这就回到了n=2的情况,b柱相当于是n=2时的a柱,a 柱相当于是n=2时的b柱,c柱还是c柱。然后,我们遵循上面的方法,把此时的b柱的小盘移到a柱,再把b柱的中盘移到c柱,最后把a柱的小盘移到c柱,成功。即
A --> C A --> B C --> B A --> C B --> A B --> C A --> C
终于弄明白了这个游戏的原理。接下来就是把这个思路通过代码表现出来了。
单独列出n=1,return用于结束递归。
move(n-1, a, c, b)
这段代码就是表示把刚才所说的a柱的上面的n-1个,通过c按照从小到大的规则先移动到缓冲区b。此函数进入递归。
move(n-1, b , a, c)
就是刚才把a上面的n-1个都移动到了b上面,肯定要通过a移动到c才能完成整个汉诺塔的移动啊,于是最后一步自然是把刚才的n-1个通过a当缓冲区移动到c柱上.
递归这段,结合我之前的思路中“b柱变a柱,a柱变b柱,c柱还是c柱”,可以发现确实是这样转变了参数顺序。
当n=4的过程就不再推演了,结果如下:
A –> B
A –> C
B –> C
A –> B
C –> A
C –> B
A –> B
A –> C
B –> C
B –> A
C –> A
B –> C
A –> B
A –> C
B –> C