汉诺塔游戏

汉诺塔游戏

汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往上按大小顺序摞着64片黄金圆盘。上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一回只能移动一个圆盘。

 

如何解决汉诺塔问题?

要想玩转汉诺塔,需要先理解递归

如果一个问题可以不断地分解为类型相同,规模更小的子问题,并且有明确的最小规模边界,,那么这个问题就可以用递归来解决:

要想解决这个问题,就必须先解决它的子问题,要想解决它的子问题,就必须先解决它的子问题的子问题...这就是递归的“递”;

当子问题减小到一定规模,可以根据明确的已知条件,将此时的子问题直接解决,这就是递归边界。然后拿着计算结果返回解决它的父问题,继而解决它父问题的父问题...最终整个问题得以解决,这就是递归的“归”。

汉诺塔就是典型的递归问题。

 

理解了递归,再来看一下解决汉诺塔问题的思路:

我们将第1根柱子上的前n-1个盘子看作一个整体,将它移动到第2根柱子上;
然后将第1根柱子上的第n个盘子移动到第3根柱子上;
再然后将第2根柱子上的前所有盘子,也就是前n-1个盘子,作为一个整体,移动到第3根柱子上,完成汉诺塔游戏。

这样,问题的规模是不是就缩小了?要完成汉诺塔游戏,我们只需要知道前n-1个盘子是怎样从第1根柱子移动到第2根柱子上就可以了。

同理我们再将前n-2个盘子看作一个整体,将它从第1根柱子移动到第2根柱子上;
然后将第n-1个盘子移动到第3根柱子上;
再然后将第2根柱子上的所有盘子,也就是前n-2个盘子,作为一个整体,移动到第3根柱子上;
最后将在第3根柱子上的所有盘子,也就是前n-1个盘子,作为一个整体,移动到第2根柱子上,至此,第1柱子上的前n-1个盘子移动到了第2根柱子上。

可以看出,要想知道前n-1个盘子如何从第1根柱子移动到第2根柱子上,只需要知道前n-2个盘子是如何从第1根柱子移动到第2根柱子上就可以了,问题规模进一步缩小。

当问题规模缩小到只剩下1个盘子的时候,问题变得非常简单,即直接将它从第1根柱子移动到第2根柱子上,然后就是回归的过程。

 

代码(C++):

void hanno(int n, char a, char b, char c) { //盘子个数为n,a,b,c分别代表左中右三根柱子
    if(n > 0) {
        hanno(n-1, a, c, b); //将a柱子上的前n-1个盘子作为一个整体,移动到第b柱子上
        cout << n << ":" << a << "->" << c << endl; //将a柱子上的第n个盘子移动到c柱子上               
        hanno(n-1, b, a, c); //将b柱子上的n-1个盘子作为一个整体,移动到c柱子上
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值