汉诺塔问题是一个经典的递归例子。这个问题是将指定个数而大小互不相同的盘子从一个塔移动到另一个塔上,移动时要遵循以下规则:
- n个盘子从上到下依次标记为1,2,3,...,n,而三个塔标记为A、B、C。
- 任何时候盘子都不能放在比它小的盘子的上方。
- 初始状态时,所有的盘子都放在塔A上。
- 每次只能移动一个盘子,并且这个盘子必须在塔顶的位置。
这个问题的目标是借助塔C把所有的盘子从塔A移到塔B。例如,如果有三个盘子,将所有的盘子从塔A移到塔B的步骤如图所示:
在三个盘子的基础上,可以手动找出解决方案,然而,当盘子的数量较大时,即使是四个盘子,这个问题还是非常复杂的。幸运的是,这个问题本身就具有递归性质。
问题的基础情况是n=1,若n==1,就可以简单地把盘子从A移到B。当n>1时,可以将原始问题拆成下面三个子问题,然后依次解决。
1)借助塔B将前n-1个盘子从A移到C。
2)将盘子n从A移到B。
3)借助塔A将n-1个盘子从C移到B。
下面是用java代码实现
package exercise.TowerOfHanoi;
import java.util.Scanner;
public class TowerHanoi {
public static void main(String[] args) {
//创建Scanner对象
Scanner input =new Scanner(System.in);
System.out.println("请输入盘子的数量n=:");
int n=input.nextInt();
//调用moveDisks方法
System.out.println("移动过程如下:");
moveDisks(n, 'A', 'B', 'C');
}
//汉诺塔
public static void moveDisks(int n,char fromTower,char toTower,char auxTower){
if(n==1){ //终止条件
System.out.println("将盘子"+n+"从"+fromTower+"移动到"+toTower);
}else{
moveDisks(n-1,fromTower,auxTower,toTower);
System.out.println("将盘子"+n+"从"+fromTower+"移动到"+toTower);
moveDisks(n-1,auxTower,toTower,fromTower);
}
}
}
实现结果如下:
请输入盘子的数量n=:3
移动过程如下:
将盘子1从A移动到B
将盘子2从A移动到C
将盘子1从B移动到C
将盘子3从A移动到B
将盘子1从C移动到A
将盘子2从C移动到B
将盘子1从A移动到B。
请输入盘子的数量n=:4
移动过程如下:
将盘子1从A移动到C
将盘子2从A移动到B
将盘子1从C移动到B
将盘子3从A移动到C
将盘子1从B移动到A
将盘子2从B移动到C
将盘子1从A移动到C
将盘子4从A移动到B
将盘子1从C移动到B
将盘子2从C移动到A
将盘子1从B移动到A
将盘子3从C移动到B
将盘子1从A移动到C
将盘子2从A移动到B
将盘子1从C移动到B。