汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
我们假定三个柱子是A B C,A是起始柱子,B是过渡柱子,C是目标柱子,我们需要借助B将A上的所有盘子转移到C上
从简单的开始看
1、假设A上只有一个圆盘,那么我们直接从A移动到C即可,只需要移动1步
2、假设A上有两个盘子,那么需要借助B来将所有盘子移动到C上,共需要3步
3、若A上有3个盘子,我们首先需要将1号盘子放在C上,再将2号盘子放在B上,之后将1号盘子放在B上,将3号盘子放在C上,接着将1号盘子放在A上,将2号盘子放在C上,最后将1号盘子放在C上,一共需要7步
以此类推,假设我们一共有n个盘子,我们的主要逻辑是先将A上的n-1个盘子通过C全部放在B上,然后将最大的盘子从A放到C上,之后将n-1个盘子通过A放在C上
public class hanoiTower {
//递归求解汉诺塔问题
/**
* 汉诺塔方法,将n号盘子从a通过b移动到c上
* @param n //一共有n个盘子
* @param a //起始柱子
* @param b //过渡柱子
* @param c //目标柱子
*/
public static void hanoi(int n,char a,char b,char c){
if(n==1)
{
move(n,a,c); //当只有一个盘子的时候直接从A移动到C
return;
}
hanoi(n-1,a,c,b); //首先把n-1个盘子从A通过C移动到B上
move(n,a,c); //A上剩下一个最大的盘子直接移动到C上
hanoi(n-1,b,a,c); //再将剩下n-1个盘子通过A移动到C上
}
static int count=0; //定义一个全局变量,计算移动的次数
/**
* 这是一个将盘子移动输出的方法,输出a->b
* @param n 第n个盘子将进行移动
* @param a 起始盘子
* @param b 目标盘子
*/
public static void move(int n,char a,char b){
count++; //每移动一次count++
System.out.println("把第"+n+"个盘子从"+a+"—>"+b);
}
public static void main(String[] args){
//递归求解汉诺塔问题
Scanner scanner=new Scanner(System.in);
System.out.print("请输入共有几个圆盘:");
int x=scanner.nextInt(); //输入共有x个盘子
char a='A'; //假设第一个柱子叫A
char b='B'; //假设第一个柱子叫B
char c='C'; //假设第一个柱子叫C
hanoi(x,a,b,c);
System.out.println("共移动了"+count+"次");
}
}
运行结果
我们可以发现当有n个盘子的时候就会移动[(2^n)- 1 ]次,才能将所有的盘子从A移动到C上