1.问题:
有三根相邻的柱子,标号为A,B,C。A柱子上从下到上按金字塔状叠放着n个不同大小的圆盘。现在把所有盘子一个一个移动到柱子B上,并且每次移动同一根柱子上都不能出现大盘子在小盘子上方。为了方便说明,这里取n=3。
2.如图
![]() |
根据题目,目的是把A上的盘子按照一定规则移动到B盘上,C柱只是一个辅助。在这里我们统一规定:资源地(A柱)、目的地(B柱)、C(辅助的柱子)。
3.解题思想:
(1)我们可以这样思考:
- 要把123转移到B(目的地)上,
- 就首先把12转移到C(辅助的柱子)上,
- 然后把3转移到B(目的地)柱上,
那现在的结果如图:
![]() |
(2)接下来这样思考:
- 要把12转移到B柱上,
- 就先把1转移到A柱上,
- 再把2转移到B柱上
结果如图:
![]() |
(3)最后把1直接转移到B柱上,这里就不画图了。
(4)总结前面的三步:
- 我们发现B柱永远都是作为“目的地”;
- A柱与C柱的作用互换:在(1)中A柱作为“资源地”,C柱作为“辅助的柱子”;在(2)中A柱作为“辅助柱子”,C柱子作为“资源地”;在(3)中A柱子又作为“资源地”,C柱子又作为“辅助的柱子”,尽管这一步没有用到C柱子;
4.编程思想:递归
- 用递归的思想编程,分为三步:重复、变化、边界
- 重复:把盘子不断的从资源地转移到目的地,同时要利用辅助的柱子;第一次把n个盘子转移到目的地,但要先把n-1个盘子转移到辅助的柱子;第二次n-1个盘子转移到目的地,但要先把n-2个盘子转移到辅助的柱子上;后面的以此类推;
- 变化:资源地与辅助地所对应的柱子每一次都在互换;n不断变小;
- 边界:当n=1时,把最后一个盘子从资源地转移到目标地,并结束递归循环;
5.代码(Java)
/**
* move(盘子个数,资源地,目的地,辅助地)
*/
public class Main {
static int N=3;
public static void main(String[] args) {
//把n个盘子从A(资源地)柱转移到B(目的地)柱子上,C柱子作为“辅助的柱子”
move(N,"A","B","C");
}
private static void move(int n, String A, String B, String C) {
//n=1时,把最后一个盘子从A柱(资源地)转移到B柱(目的地)上,并结束递归
if(n==1){
System.out.println("把 "+n+" from "+A+" to "+B+","+C+" as a helper!");
return;
}
//先把n-1个盘子从A柱(资源地)转移到C柱(目的地)上,B柱作为“辅助的柱子”
move(n-1,A,C,B);
//再把第n个盘子从A柱(资源地)转移到B柱(目的地)上,C柱作为“辅助的柱子”
System.out.println("把 "+n+" from "+A+" to "+B+","+C+" as a helper!");
//把n-1个盘子从C柱(资源地)转移到B柱(目的地)上,A柱作为“辅助的柱子”
move(n-1,C,B,A);
}
}
以上是我用递归方式求解汉诺塔问题的方法,希望对您有帮助。