递归解决汉诺塔问题
有没有人想在了解递归后想自己动手实践下? 了解到汉诺塔问题可以用递归解决后, 我决定自己尝试下 :
先说下我的思路 :
递归的思路:
递归一般用来解决的问题: 如果这个问题的上一步解决了, 问题的这一步应该很好处理
所以思考递归应该采用逆向思维, 在解决上一步问题的基础上, 应该做什么?
在写递归时,我们只需要确定两个条件:
1.递归的核心公式是什么?
2.递归何时结束?
对于汉诺塔问题的分析
举个例子:
* 1.要解决把4个数从A柱移动到C柱 1234, A-->C
* 在解决了上一步, 也就是解决了[移动3个数]问题的基础上进行思考
* 我们需要解决三个步骤: [123,A-->B] (4,A-->C) [123,B-->C]
*
* 2.以123,A--B为例
* 需要解决三个步骤: [12,A-->C] (3,A-->B) [12,C--B]
*
* 依次类推....
*
* 3.递归终止的条件
* 当需移动的数个数为1时, 递归结束 打印移动步骤
*/
递归方法的设计
解决汉诺塔问题, 还需要处理一个小问题:
怎么在已知两个柱子的基础上求出第三个柱, 有很多种实现方式
我发现一个有趣的算法 对于 -1, 0 , 1三个数, 不管传入哪两个数, 第三个数都是两个数的和取负, 即 c = - (a + b)
写递归方法
递归方法写的只是一个公式,
处理把解决这一步的方法, 通过解决上一步来实现
并且定义第一步的实际处理方式作为递归的终止条件
/**
* @param length 要移动几个数(从上到下正序排列)
* @param src 从哪个柱子移动
* @param dest 移动到哪个柱子
*/
private static void hanoiTowelMove(int length, int src, int dest) {
if (length == 1) {//终止条件
System.out.println("把" + length + "从" + src + "移动到" + dest);
} else {
//第一个步骤, 通过上一步来解决
hanoiTowelMove(length - 1, src, (src + dest) * -1);
//第二个步骤, 直接打印吧
System.out.println("把" + length + "从" + src + "移动到" + dest);
//第三个步骤, 通过上一步来解决
hanoiTowelMove(length - 1, (src + dest) * -1, dest);
}
}
方法的调用
/**
* 用-1,0,1代表三个柱子,需要通过其中两个数就能求出第三个数
* c = - (a + b), 正好可以计算第三个数
*/
hanoiTowelMove(3, -1, 1);
美化一下
…
算了, 有兴趣的自己美化下吧