汉诺塔

自己对汉诺塔递归的理解

汉诺塔大家都很熟悉,抽象出来就是在{A【】, B【】,C【】}这三根柱子上,A上有从上至下逐渐增大的圆盘n个,我们要借助B柱将A柱上的圆盘依旧按照从上之下逐渐增大的序列移到C柱。
代码如下:
void hanhuota(A, B, C, n){
if(n == 1)
move(A, C);
else{
hannuota(A, C, B, n-1);
move(A, C);
hannuota(B, A, C, n-1);
}
代码大家肯定都已经很熟悉了,但是如何深刻的理解汉诺塔这个问题就不是那么简单了,我也是花了好大一番功夫才给理解透彻的。在这里我将说一下在查资料的时候没看到有人说的、我自己理解到的部分。
在解决这个问题的时候我们要先知道这么几点:
1.我们的最终目的是让A上的圆盘全都移到C上
2.如果A上只有最大的那一个圆盘,那么我们就可以把A上的唯一圆盘直接移到C上,并且C上 所有的那个最大的圆盘可以看做C的一部分,换句话来说就是把它忽略(因为最大的那个已经到达目的地了,在之后的移动中我们都不会再去移动它了)
3.为了让A上只剩下最大的那个圆盘,我们可以让A上的n-1 个圆盘先移到B上

首先我们来让n等于4,那么就{A【4,3, 2,1】,B【】, C【】}这样的存在,那么函数应该是这样的:hannuota(A, B, C, 4); 为了将A上的最大的那个圆盘(也就是圆盘n)移到C上,我们要先将A上的n-1个圆盘移到B上,即将A【4,== 3, 2, 1==】中的【3, 2, 1】移到B上。这里注意,我们初始目的是将A上的4个圆盘移到C上,B盘不进行操作,所以我们的函数是hannuota(A, B, C, 4); 而这里我们为了将A盘上的3个圆盘移到B上,很理所应当的,我们的函数是hanhuota(A, C, B, 3)(3=4-1);
然后,情况就变成了这样{A【4】, B【3, 2,1】, C【】};现在A柱上只剩下最大的圆盘了,只要将这个最大的圆盘移到C柱上,我们就完成了一次成功的移盘操作,所以进行move(A, C);
此时情况变成了这样{A【】,B【3, 2,1】, C【4】},因为C柱上的圆盘已经是最大的了,在之后的移动中我们都不再去对它进行操作,所以将它忽略,这样就变成了{A【】,B【3, 2, 1】, C【】};现在我们来观察一下,是不是感觉这个情况很熟悉?现在的B变成了初始状态的A,现在的A变成了初始状态的B,想将B上的圆盘按大小顺序移到C上,我们又要将B上的前n-1个圆盘移到A上,然后再将B上最大的圆盘移到C上。此时的操作就变成了函数hannuota(B, A, C ,n-1)。
如此递归,一直让函数hanhuota(A , B, C, n)中,参数A上圆盘的数量与参数n相对应, 并且一直让需要将前n-1个圆盘移动的柱子放在参数A的位置;如此递归下去,直到n等于1,说明在A柱上较大的那n-1个圆盘都已经有序放在了C柱上,在A柱上的是最小 那个圆盘,此时直接执行move(A, C)操作就可以完成整个移动过程了。

我们知道在设计递归算法的时候有两个重要部分不能少:基准情形和不断推进。基准情形是算法结束的条件,不断推进则是要求我们在算法中要使条件不断的从初始情况向基准情行靠近,因为只有这样我们才能保证算法的有穷性。在hannuota函数中,n = 1 就是基准情形。

这是我的第一篇博客,对于很多操作都不熟悉,所以看起来不是很整洁,还请大家多多包涵

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值