求真正理解汉诺塔问题的编程大神回答一下,当n=3时,用c语言编写的汉诺塔递归调用代码的详细执行过程

求真正理解汉诺塔问题的编程大神回答一下,当n=3时,用c语言编写的汉诺塔递归调用代码的详细执行过程,要详细!!!!给分100。。。谢谢大神!!!... 求真正理解汉诺塔问题的编程大神回答一下,当n=3时,用c语言编写的汉诺塔递归调用代码的详细执行过程,要详细!!!!给分100。。。谢谢大神!!! 展开
 我来答
我爱上那女孩
2014-11-27 · TA获得超过466个赞
知道小有建树答主
回答量:177
采纳率:0%
帮助的人:132万
展开全部

一开始我接触汉诺塔也是很不解,随着代码量的积累,现在很容易就看懂了,因此楼主主要还是对递归函数的理解不够深刻,建议你多写一些递归程序,熟练了自己就能理解。


圆盘逻辑移动过程+程序递归过程分析


Hanoi塔问题, 算法分析如下,设A上有n个盘子,为了便于理解我将n个盘子从上到下编号1-n,标记为盘子1,盘子2......盘子n。


如果n=1,则将“ 圆盘1 ” 从  A 直接移动到 C。


如果n=2,则:

(1)将A上的n-1(等于1)个圆盘移到B上,也就是把盘1移动到B上;

(2)再将A上 “盘2” 移到C上;

(3)最后将B上的n-1(等于1)个圆盘移到C上,也就是第(1)步中放在B上的盘1移动到C上。

    注意:在这里由于超过了1个盘子,因此不能直接把盘子从A移动到C上,要借助B,那 么 hanoi(n,one,two,three)的含义就是由n个盘子,从one移动到three,如果n>2 那么就进行递归,如果n=1,那么就直接移动。

       具体流程:

       Hanoi(2,A,B,C);由于2>1因此进入了递归的环节中。

    <1>执行hanoi(1,A,C,B):这里就是刚才的步骤(1),代表借助C柱子,将A柱子上的  1个圆盘(盘1)移动到B柱子,其实由于是n=1,此时C柱子并没被用到,而是直接移动了。

    <2>执行hanoi(1,A,B,C):这是步骤(2),借助B柱子,将A柱子上的一个圆盘(盘2)移动到C柱子上。这里由于也是n=1,也并没有真正借助B柱子,直接移动的。

    <3>执行hanoi(1,B,A,C):这是步骤(3),将B上的一个盘子(盘1)移动到C

    函数中由于每次调用hanoi的n值都是1,那么都不会进入递归中,都是直接执行了mov移动函数。


如果n=3,则:(倒着想会想明白)移动的倒数第二部,必然是下面的情况

(1)将A上的n`-1(等于2)个圆盘移到C上,也就是将盘1、盘2 此时都在B柱子上,只有这样才能移动最下面的盘子(盘3)。那么由于现在我们先忽略的最大的盘子(盘3),那么我们现在的目标就是,将两个盘子(盘1、盘2)从A柱子上,借助C柱  子,移动到B柱子上来,这个过程是上面n=2的时候的移动过程,n=2的移动过程是“2     个盘子,从柱子A,借助柱子B,移动到柱子C”。现在是“2个盘子,从柱子A,借助柱子 C,移动到柱子B上”。因此移动过程直接调用n=2的移动过程就能实现。

(2)将A上的一个圆盘(盘3)移到C。

(3)到这一步,由于已经将最大的盘子(盘3)移动到了目的地,此时无论后面怎么移动都不需要在用到最大的那个盘子(盘3),我们就先忽略他,剩下的目标就是将B上面的n-1个盘子(盘1、盘2)移动到C上,由于A上没有盘子了,此时要完成上面的目标,就要借助A盘子。最终达到的目标就是将B上的2个盘子,借助A移动到C上,这个过程就是当n=2时分析的过程了,仅仅是最开始的柱子(B柱子)和被借助的柱子(A柱子)不同了。所以直接调用n=2时候的过程就能股实现了。

具体执行过程:

Hanoi(3,A,B,C);由于3>1因此进入了递归的环节中。

       <1>执行hanoi(2,A,C,B):这里代表刚才的步骤(1),将两个盘子(盘1、盘2)从A移动到B,中间借助C。根据n=2的分析过程,必然是能够达到我们的目的。

       <2>执行hanoi(1,A,B,C):现在A上只有一个盘子(盘3),直接移动到C上面即可。

       <3>执行hanoi(2,B,A,C):此时对应步骤(3),剩下的目标就是将B上的两个盘子,借助A移动到C上。那么同样根据n=2的移动过程,必然能达到目的。

 

最终实现了3个盘子从A,借助B移动到了C。


更多追问追答
追问
非常感谢!很认真的看了一遍!真心不好意思,你写了那么多,不过我已经采纳了,,不好意思啊,
追答
我写的时候他们就回答了,只是因为我开始对这个程序也不理解,看到你也不懂,就特别想解决你的疑问。因此我仔细研究了下如何能够明了的讲解这个过程。最终目的:你懂了就好了~~~
汗会欣Q9
推荐于2017-11-25 · TA获得超过1660个赞
知道小有建树答主
回答量:1242
采纳率:81%
帮助的人:628万
展开全部
/* 汉诺塔 hannota.c */
#include<stdio.h>
/*
解法:
如果柱子标为ABC,要由A搬至C,在只有一个盘子时,就将它直接搬至C,当有两个盘子,就将B当作辅助柱。
如果盘数超过2个,将第三个以下的盘子遮起来,就很简单了,每次处理两个盘子,也就是:A->B、A->C、B->C这三个步骤,而被遮住的部份,其实就是进入程式的递回处理。
事实上,若有n个盘子,则移动完毕所需之次数为2^n-1;
所以当盘数为64时,则 64所需次数为:2^63=8446744073709551615为5.05390248594782e+16年,
也就是约5000世纪,如果对这数字没什幺概念,就假设每秒钟搬一个盘子好了,也要约5850亿年左右
*/
void HanNoTa ( int n,char A,char B,char C )
{
if ( n==1 )
{
printf ( "盘%d 由 %c 移至 %c\n",n,A,C );
}
else
{
HanNoTa( n-1,A,C,B );
printf( "盘%d 由 %c 移至 %c\n",n,A,C );
HanNoTa( n-1,B,A,C );
}
}

int main()
{
int n;
printf( "请输入盘数:" );
scanf( "%d",&n );
HanNoTa( n,'A','B','C' );
return 0;
}
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
linnjing
推荐于2017-09-14 · TA获得超过2632个赞
知道大有可为答主
回答量:1230
采纳率:91%
帮助的人:521万
展开全部
理解汉诺塔问题,可以先抛开递归这件事,就问题本身来讨论,先不要看程序。
三个柱子上,小的圆盘一定在大的上面。把A柱上的盘子n号盘子移到B柱上,分成两步,1)把n之前的移走,2)把n号盘移到B柱上,3)把n之前的盘子移回来。

先把这个问题本身搞清楚,再来讨论程序实现。
把n之前的盘子移走这个事,不是简单的一次就可以移走的,这是一个过程。
这个过程要借助C柱,
移动n-1个盘子的过程,与移动n个盘子的过程相比,除了数量少一个,目标是A到C,没有本质的不同,这也是使用递归的基础。
把解决问题的过程弄明白了,再来看程序就比较容易了。

n=3,移动3个盘子
实际上我们如果手工去做,要这样,
1# A-B
2# A-C
1# B-C
3# A-B,这时3#已经就位。
1# C-A
2# C-B
1# A-B
这是移动3个盘子,从A-B。
要移动第4个盘子,这时就可以做了 4# A-C,然后重复前面的过程,把3个盘子移动到过来。
不过刚才移动的3个盘子是A-B,现在则是B-C,但基本的过程是一样的。

具体 的程序看百科看吧。
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式