汉诺塔问题是一个简单又经典的递归问题。
题目描述
汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?
汉诺塔问题的解决思路及算法
假设3根柱子分别为A、B、C,圆盘数目为n.
1. n=1 , 如果A有一个圆盘,则直接移动至C。
2. n=2, 如果A有2个圆盘,则A->B, A->C , B->C。
假设当我们在数目为n-1的时候已经解决了移动问题可以成功移动至C,如果又多一个呢,即n,我们用同样的方法把圆盘移动至B(我们已经可以把n-1个盘子通过B移动至C了,那么通过移动至B也一样),为什么移动至B了呢,因为多了个盘子(放在最底部的大盘子),我们要向步骤2一样把上面的n-1个盘子看成一个整体,用上一个方法即移动n-1个盘子的方法把上面的n-1个盘子移动至B,然后把新增的那个大盘子移动至 C ,然后再用移动n-1个盘子对应的方法把B中的n-1个盘子移动至C,就完成了。
假设n = n 时,
步骤1: 将n-1个盘子从A移动到B(借助C),A上剩余一个盘子。
步骤2: 将A上的一个盘子,移动到C,在将B上的盘子移动到C,及完成有A到C盘子的移动。
算法实现:
void hanoi(char A, char B, char C , int n) //借助B柱子,将A上的盘子移动到C
{
if(n == 1)
{
cout<<A<<"->"<<C<<endl; //如果只有一个盘子不需要借助任何柱子,即可以进行移动
}
else
{
hanoi(A,C,B,n-1); //如果不至一个盘子,则调用移动n-1个盘子,借助C,从A移到B
cout<<A<<"->"<<C<<endl; //将A中剩余的一个盘子移动到C
hanoi(B,A,C,n-1); //将B上的n-1个盘子,借助A,移动到C
}
}