c语言递归汉诺塔次数,c语言递归解决汉诺塔参数变化的疑惑

c语言递归解决汉诺塔参数变化的疑惑

答案:3  信息版本:手机版

解决时间 2020-04-05 14:20

已解决

2020-04-05 10:49

#include void main()

{void hanoi(int n,char one,char two,char three);

int m;

printf("input the number of disks:");

scanf("%d",&m);

printf("the step to moving %d disks:\n",m);

hanoi(m,'A','B','C');

}

void hanoi(int n,char one,char two,char three)

{void move(char x,char y);

if (n==1) move(one,three);

else

{hanoi(n-1,one,three,two);

move(one,three);

hanoi(n-1,two,one,three);

}

}

void move(char x,char y)

{

printf("%c-->%c\n",x,y);

}

谭浩强的书上的程序,我知道一步步的调用顺序,明白算法,但我不知道怎么实现的,就是在每一次调用hannuota时,one two three所对应的字母不理解,忘给我解释一下,最好把每一次调用h函数及move函数的 one two three的对应值写出,谢谢!

全部回答

1楼

2020-04-05 13:22

你要倒着想这个问题的顺序。要解决汉诺塔问题,就要从地基开始考虑。电脑解决的思路是假设最后一步是这样的:最小的一片在a柱子上,其他的片排好了在c柱子上。那么这时,问题就可以变成把最小的一片挪到c柱子就完结了。那么往前反推,怎样能造成最后一步这样的场景?

我们这里假设有n片需要移到c柱子上去。如果能把最大的一片按规则移到c柱子,那一片就变成了我们不用考虑的地基,以后任何的移动都与他无关,然后再考虑剩下的n-1片,那么问题的规模就会逐步缩小,逐渐缩小到电脑假设的最后一步。那么什么情况下当前最大的一片可以移到c上呢?就是当其他比他小的n-1片都在b上了,他才能顺利移到c上。这就是电脑解汉诺塔的基本思路,类似于逆推法。如果你理解了电脑解答这个问题的基本思路,就能理解这个算法了。

回到你的具体问题。n=3。有3片需要移动,从小到大编号为1、2、3,柱子分别为one(a),two(b),three(c),则步骤如下:

1. 为了使3号片顺利到c,那么前提是1、2号片顺利到b。

2. 1、2号到b,前提是2顺利到b

3. 2顺利到b,前提是1到c

4. 1可以成功到c,此时逆推过程,得解答

2楼

2020-04-05 12:55

这种实现方法是递归的方法来是实现的,递归的实现离不开栈。首先第一个主函数调用

hanoi(m,'A','B','C');(把A中的m个盘子利用B移动到C)在这个函数体内他由调移到hanoi(n-1,‘A’,‘C’,‘B’);(把A的前n-1个盘子利用C移到B)此时hanoi(m,'A','B','C');在cpu中的环境入栈,hanoi(n-1,‘A’,‘C’,‘B’);的各个环境参数进驻cpu而他又调用hanoi(n-3,,‘A’,‘B,‘C);依次类推....直到第一个参数n==1为止就把A上的最后一个盘子移到另一个柱子上,然后返回...最后hanoi(n-1,‘A’,‘C’,‘B’)函数返回,执行move(’A‘,'C‘);把A移动到C上。再执行hanoi(n-1,‘B,‘A,‘C);他的执行步骤和hanoi(n-1,‘A’,‘C’,‘B’)一样,就不在解释

3楼

2020-04-05 11:31

汉诺塔问题是非常经典的递归问题,可以这么讲,真正领会递归不是一两天的事情。然而递归又是算法的基础,你必须掌握。

其实只要抓住两点

1、递归体(递归到底要实现什么)

2、递归出口(任何递归都有一个出口)

好了现在来看这个问题

A B C

ABC三堆,将A堆盘子通过B堆过渡,送到C堆,要求每一次送的时候大盘子在下面

此题的递归思想:将A堆中上面的n-1(假设n个)个盘子送到B堆上,再把A堆中最大的盘子

送到C堆上,最后将B堆中n-1个盘子送到C堆上就OK啦

上面的就是递归体,而递归的出口在哪里呢?显然当n=1时这个就是递归的出口

下面来看你的程序

one--------A堆

two---------B堆

three-------C堆

#include void main()

{void hanoi(int n,char one,char two,char three);

int m;

printf("input the number of disks:");

scanf("%d",&m);

printf("the step to moving %d disks:\n",m);

hanoi(m,'A','B','C');

}

void hanoi(int n,char one,char two,char three)

{void move(char x,char y);

if (n==1) move(one,three);//只有一个盘子的时候直接送到C堆上

else

{hanoi(n-1,one,three,two);//不值一个盘子时候,将A上面的n-1个盘子通过C堆送到B堆上

move(one,three);//上面送完了之后,将A堆中最大盘送到C堆上

hanoi(n-1,two,one,three);//最后将B堆送到C堆上完毕(通过A过渡)

}//上面的三句话就是递归体,至于他的过程你是无法跟中的,但是思想是很明确的

}

void move(char x,char y)

{

printf("%c-->%c\n",x,y);

}

PS:那些字符只是个标记而已,不要迷惑他们。。。

我要举报

如果感觉以上信息为低俗/不良/侵权的信息,可以点下面链接进行举报,我们会做出相应处理,感谢你的支持!

大家都在看

推荐资讯

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值