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:那些字符只是个标记而已,不要迷惑他们。。。
我要举报
如果感觉以上信息为低俗/不良/侵权的信息,可以点下面链接进行举报,我们会做出相应处理,感谢你的支持!
大家都在看
推荐资讯