汉诺塔c语言

void hannuo(int n, char x, char y, char z) //把 n 个盘从 x柱借助y柱移动到z柱
{
	if(n == 1) printf("Move %d %c -> %c\n", n, x, z); // 只有一块盘时,直接把它移到z柱
	else 
	{
		hannuo(n - 1, x, z, y); //把 n - 1 个盘从 x柱借助z柱移动到y柱
		printf("Move %d %c -> %c\n", n, x, z); //把第n个盘从x柱直接移到z柱
		hannuo(n - 1, y, x, z); //把 n - 1 个盘从 y柱借助x柱移动到z柱
	}
}


记得上面的汉诺塔代码大一上的时候,看了好久都没看懂,今天上课的时候又碰到他了,所以,现在重新理解一遍。

上面的代码是一个递归的过程,他的递归出口是n = 1 的时候。当n = 1的时候,直接把盘子放到目的地就好了,这个问题不大。

然后看到下面的 else部分,

里面的第一句是把左柱子的最下面的一块盘上的所有盘子先放到中间的柱子,

然后第二句是说,把左柱子的最下面的盘子(现在左柱子就这一块盘子)放到最右边的柱子,

最后一句就是说把那些在中间柱子的盘子都放到最右边的柱子。


这里为了简化这个问题,我们先来讨论n = 2 时候的情况,

刚开始的时候 n > 1 进入到else部分,这里我们要注意一下,他这里的else部分里的第一句,n - 1 就是将原先的移动n个汉诺塔的问题分解成一个移动 n - 1个汉诺塔的问题,那么问题来了,为什么他这样分解不会出错呢?这样分解你难道不会产生大盘子放在小盘子上的问题么?

呵呵,你仔细看一下这个递归函数里的后面三个变量,分别是x , z , y.嗯,你发现了什么?是的,我们传进去的是x , y , z . 而当我们要对他进行分解的时候,却变成了x , z , y .  那么为什么我们要这样做呢?

这里我们先来看看n == 1 时的那个情况,请你快速的回答我,这个情况输出的是什么? 对的,当只有一块盘子的时候,我们直接将那个盘子从最左边柱子移到最右边。也就是输出x -> z;

然后我们回过头去看看else里的第一句,此时他的意思就是将最左边的第一个盘子移到中间,然后第二句的意思就是将第二个盘子移到最右边,最后一句就是将中间的盘子移到最右边。

这里可能文字的描述有点晦涩,我们来看看下图,我们用红,棕,蓝三种颜色分别表示初始的左中右三个位置,那么我们这里看到(注意柱子的颜色),在进行else语句里的第一句的递归时,他的y与z(实际的中间的位置和右边的位置)进行了交换,那么这样就能保证,大盘子不会放到小盘子之上.他的整个过程就是利用不断的交换y与z的位置,并且对n的数目进行分解。


其实,你只要在纸上写出n = 2的时候的过程,那么你就会明了很多。

当n = 2这个过程你理解之后,n > 2的过程实际上也是在这个n = 2的过程上进行的,嗯,好好理解一下,相信你会很快明白的。


that‘s all...

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值