-
-
[原创]关于hanoi塔的思路分析
-
发表于:
2012-3-18 11:37
3188
-
关于hanoi塔问题程序设计思路的分析
这段时间抽空复习了一遍谭浩强的C语言,又学到了不少东西,这其中就包括这个hanoi塔的问题。他以递归调用的的方法编写的程序,之前没注意,这次仔细分析了一下,下面是我的分析思路,拿出来和大家分享。
首先介绍一下什么是hanoi问题(其实大家都应该见过这个问题的,只不过可能记不起这个名字了):
一块板上有三根针,A,B,C。A针上套有n个大小不等的圆盘,大的在下,小的在上。要把这n个圆盘从A针移动C针上,每次只能移动一个圆盘,移动可以借助B针进行。但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上。求移动的步骤。
我们先自己分析一下思路。首先我们采用,特殊值,取我们很容易就能得解的n=1,n=2,n=3(这种方法想必大家在程序设计中经常用到的)。
N=1时,把圆盘移动到C针,需要一步,AC;
N=2时,把圆盘移动到C针,需要三步,AB,AC,BC;
N=3时,把圆盘移动到C针,需要几步呢?没那么容易了吧?一眼看不出来了吧?哈哈….不难为大家,我就直接给出了,AC,AB,CB,AC,BA,AC,共七步;
那么N=n呢?呵呵…这个我想给也给不出来了,那么就让我们分析一下,其中有没有相似的步骤吧,毕竟只有有了相似的步骤才能使用递归调用。
这里我们可以做假设一,把A针上的n个圆盘假设成为两个,其中一个是最下面那个最大的盘,另一个就是剩下的n-1个盘,这样是不是就变成n=2时的情形?
AB A:1 B:n-1 C:0;
AC A:0 B:n-1 C:1;
BC A:0 B:0 C:n;
有没有发现,在第二步的时候,A针为0,B针有n-1个,C针有一个,但是却是最大的那个,所以我们又可以做出新的假设了——假设二,把B针看作是A针,那么我们现在的任务便是要把B上的n-1个盘移动到C针上面。呵呵…那是不是又可以做上面的那个假设了?
A(B)B(A) A(B):1 B(A):n-1-1 C:0;
A(B)C A(B):0 B(A):n-1-1 C:1;
B(A)C A(B):0 B(A):0 C:n-1;//括号中为真实指针!!!!
想到了吧,这样n一直减1下去的话终究会变为1的,那么问题就解决了。
但是新的问题来了,我们终究是逆向分析,第一步应该从哪里开始呢?很明显,只有A,B,C三个圆盘,第一步要么是AB,或者是AC。这似乎和我们之前分析的结果有矛盾啊?怎么办?(还能怎么办,肯定是之前分析的错了吗)
再次回到我们之前的分析,去找问题出在哪,是不是我们哪里有了疏漏。呵呵…原来是我们在第一步到第二部的时候缺了一步,那就是如何把A针上的n-1个盘挪动到B盘呢?我们可以是不是有要做新的假设了,就把这个假设的名字定为假设1.5吧(糗…..)。我们把C针看作是B针,把B针看作是C针,问题就又变成了最初的问题(哈哈…终于完成递归调用的循环了)。
好了吧?思路已经明显了,我们就来看看谭浩强的那个递归调用程序吧。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)