汉诺塔的游戏网址:http://www.hannuota.cn
Hanoi的游戏目的:打印塔A上所有的盘子移动到塔C的所有路径
规则:1.每次仅能移动一次;
2.小的金盘必须在大的金盘上面
思考任何问题我们思维上都应该先从数学的角度
去分析,而不是一上来就思考编程如何实现。
-
假令塔1有1个盘子,直接把其从塔1 -> 塔3
-
假令塔1有2个盘子,仅需要塔1 -> 塔2,塔1 -> 塔3,塔2 -> 塔3
-
假令塔1有3个盘子,需要塔1 -> 塔3,塔1 -> 塔2,塔3 -> 塔2,塔1 -> 塔3,塔2 -> 塔1,塔2 -> 塔3,塔1 -> 塔3
……
不难发现随着塔1增高,即盘子数增多,移动步骤将逐渐增多,我们再很难写出具体每步移动过程了。所以我们应思考能不能找到普遍规律……
我们不妨把最底层的盘子记为n,把其上 n-1 盘子当作一个整体来考虑,当 n-1 个塔全处在 塔2 的这种状态时(如下图例),才能符合规则将第n个盘子从 塔1 -> 塔3,然后再将被当作整体的 n-1 个盘子移动至塔3,方可完成游戏,所以这是除 n=1 的特殊情况外都必经过的状态。
所以,我们且把Hanoi游戏的步骤分为三大步骤。先不去思索具体的移动步骤,纠结于此也是徒劳。
步骤 1:塔 1的 n-1 个盘子 移动至 塔 2
步骤 2:塔 1的第 n个盘子 移动至 塔 3
步骤 3:塔 2的 n-1 个盘子 移动至 塔 3
接下来我们从编程的角度
并根据上述总结的规律思考下:
Hanoi每座塔的盘子移动是大盘先进小盘后进,小盘先出大盘而后才可出,这就似方法调用入栈和退栈的过程,"先进后出,后进先出"
,所以步骤1和步骤3的移动过程就是反反复复的入栈退栈,思索至此就知道这题使用递归恰好不过。
再来,欲要使用递归就需要两个条件:1.终止条件 2.递归通式
。
- 终止条件很简单就知道,当 n=1 时便是,只有一个盘子情况下,直接塔1 -> 塔3,Move(1,3)。
- 步骤1以 塔3为跳板 塔2为目标,步骤2直接移动,步骤3以 塔1为跳板 塔3为目标,根据三大步骤:
步骤 1:Hanoi(1,3,2)
步骤 2:Move(1,3)
步骤 3:Hanoi(2,1,3)
代码具体实现(形参和实参均换成字母):
移动函数
void Move(