汉诺塔的理解

数学思想——归纳推理(不是反证法)

为了方便,我把塔叫做牌,最左边的是从大到小(底部开始)放置的的牌堆。

所求的式把A区域的塔以同样的形状放到C区域上去,而且大一点的盘子不能放在比它小的盘子上

数字的那一列是递归调用,右边长度不一的箭头是,数字阶段向下调用方法的情况(每一次向下指的线都是一次发牌)。发牌次数加上第一次n == 1(局部变量)的那一张牌刚好就是牌堆里面的总数N张牌。

在网上找到的代码

#include<stdio.h>        //递归找 
#include<math.h>
int Hanoi_count(int n)
{
	return pow(2, n) - 1;
}
void move(int x, int y)
{
	printf("%c->%c\n", x, y);
}
void Hanoi(int n, char a, char b, char c)
{
	if (n == 1)
	{
		move(a, c);
	}
	else
	{
		Hanoi(n - 1, a, c, b);//将A座上的n-1个盘子借助C座移向B座
		move(a, c);//将A座上最后一个盘子移向C座
		Hanoi(n - 1, b, a, c);//将B座上的n-1个盘子借助A座移向C座
	}
}
//move中的实参与hanoi函数中的形参相对应,而hanoi函数中形参a,b,c所对应的值也是在有规律的变化
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = Hanoi_count(n);
	printf("%d层汉诺塔完成移动一共要%d步\n", n, ret);
	Hanoi(n, 'A', 'B', 'C');
	return 0;
}

输入1 2 3,每次第一次移动牌都会变,不是2就是3,我们从这里可以归纳出规律来——每次不同牌堆数不同的放置调整总是放到B或者C区域,可能和牌堆的数量有关。

尝试去证明——一张牌,直接放在了C区域。两张牌则是B区域开始,三张又是C区域开始了。

首先绝对不可能自己发到自己,所以只能发到B区域或者C区域。发牌区发牌的时候,两个区域都是调整区域。一张牌的时候放在C区域,2张若第一张放B区域了,2张的第二张就是C区域了,B区域的那张牌只能放在C区域的第一张牌上面了,不然就只能按大到小给放回牌堆了,或者无意义的乱。这里出现的矛盾,因此牌堆2时只能先放在B,3张牌若和2一样就也会出现矛盾,以此类推,牌堆1线性增加,每次放第一张牌的时候都是B、C、B、C区域的规律放置第一张牌的。(还可以这样解释,堆起来空起来的位置可以是要目标大盘放置的位置,只是没有物理的把盘子给交换,所以只需要调整位置即可,圆盘 A B C,C堆起来了,把B和C交换位置A C B,如果不看标记,把A的牌堆第一张牌放到大盘B上,C再借A再放一次自己的造型到B上,就是牌堆数量为n + 1的情况了)

上面的证明,其实已经证明了放一个,再放一堆的方法了的有效性了。

但是还是希望能注意到——a、b、c不是是A、B、C区域,只是一个局部变量。

void Hanoi(int n, char a, char b, char c)
{
	if (n == 1)
	{
		move(a, c);
	}
	else
	{
		Hanoi(n - 1, a, c, b);//将A座上的n-1个盘子借助C座移向B座
		move(a, c);//将A座上最后一个盘子移向C座
		Hanoi(n - 1, b, a, c);//将B座上的n-1个盘子借助A座移向C座
	}
}
Hanoi(n - 1, a, c, b);

这个a 就是A ,但是c和b就会B C、C B、C B、B C的规律变化

a不变是因为A位置永远不能有新的牌群

Hanoi(n - 1, b, a, c);

去掉中间的第二个字母,就是a到b或者b到c (b 可以是 B或者C)

move(a, c);//将A座上最后一个盘子移向C座
Hanoi(n - 1, b, a, c);//将B座上的n-1个盘子借助A座移向C座

就是发新牌,然后在把现在堆起来的新牌群的牌的造型又堆在新发的牌的上面。move(a, c);后要用Hanoi(n - 1, b, a, c);放在move(a, c);放在的盘上,要放置的操作和当初放在原来盘上一样,因为牌群数量没变,而move(a, c);放的是更大的,可以当作是盘子的一部分。

新的大盘子到达的地方,它上面完整的小于自己的牌群是一定可以到达的。

至于为什么

		Hanoi(n - 1, a, c, b);//将A座上的n-1个盘子借助C座移向B座
		move(a, c);//将A座上最后一个盘子移向C座
		Hanoi(n - 1, b, a, c);//将B座上的n-1个盘子借助A座移向C座

这里为什么n - 1最后一次可以直接一堆在C上还要

		Hanoi(n - 1, a, c, b);//将A座上的n-1个盘子借助C座移向B座

这里的n - 1出现的原因是为了递归 n - 1传到下面的n ,下面的n == n - 2,以此类推才能n == 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值