函数递归调用中 汉诺塔 有个地方不明白 求高手指点

SMouse鱼骨头 2012-09-18 06:59:37
#include<stdio.h>
int main()
{
void hanoi(int n,char one,char two,int three);
int m;
printf("请输入盘子的数目:");
scanf("%d",&m);
printf("移动 %d 个盘子需要的步骤:\n",m);
hanoi(m,'A','B','C');
return 0;
}
void hanoi(int n,char one,char two,int three)
{
void move(char x,char y);
if(n==1)
move(one,three);
else
{

}
}
void move(char x,char y)
{
printf("%c-->%c\n",x,y);
}


程序是对的,我不明白的是调用的过程,就是下面的这三句,希望高手指点,谢谢
hanoi(n-1,one,three,two);
move(one,three);
hanoi(n-1,two,one,three);
...全文
144 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
yisikaipu 2012-09-19
  • 打赏
  • 举报
回复
如下代码容易理解吧

现在就是转一下脑筋,把这三个函数写成一个函数

void hanoi1(int n,char here,char there) // 把n盘从here移到there
{
printf("move %d from %c to %c\n",n,here,there);
}

void hanoi2(char here,char temp,char there)
{
hanoi1(1,here,temp);
hanoi1(2,here,there);
hanoi1(1,temp,there);
}

void hanoi3(char here,char temp,char there)
{
hanoi2(here,there,temp);
hanoi1(3,here,there);
hanoi2(temp,here,there);
}

int main()
{
hanoi3('A','B','C'); // 从A柱移到C柱

return 0;
}
yisikaipu 2012-09-19
  • 打赏
  • 举报
回复
阶乘的例子能想明白不?只不过阶乘的例子只有1个变量,而汉诺塔是4个变量。道理是一模一样的

int fact(int n)
{
static int mark=0;
printf("times:%d, n:%d\n",mark,n);
++mark;

if(n>1)
{
int ans=n*fact(n-1);
printf("times:%d, ans:%d\n",mark,ans);
return ans;
}
else
{
int ans=1;
printf("times:%d, ans:%d\n",mark,ans);
return ans;
}
}

int main()
{
int ans=fact(3);

return 0;
}
SMouse鱼骨头 2012-09-18
  • 打赏
  • 举报
回复
很感谢各位,我现在说说我以前的想法,大家说说对不对

3个盘子的时候,m=3


haloi(3,1,2,3)

hanoi(2,1,3,2);
move(one,three);
hanoi(2,2,1,3);


hanoi(1,1,3,2);
move(one,three);
hanoi(1,2,1,3);
move(one,three);
hanoi(1,1,3,2);
move(one,three);
hanoi(1,2,1,3);

这样把我整蒙了,我现在感觉这样想好像不对,但具体我又不知道怎么回事,

当盘子是3的时候,会是7步,而上面对应的是7步,然后,每一个移动函数都是move(one,three);
这里的 one three 代表的是什么呢?

上面的
hanoi(n-1,one,three,two);//借助第二根把第一根上的 n-1 个盘子移动到第三根上
move(one,three);//把第一根上,最下面的一个(最大的)直接移动到第三根上
hanoi(n-1,two,one,three);//借助第1根把第二根上的 n-1 个盘子移动到第3根上
这个我知道,我不知道的是,接下来程序是怎么进行的,是像我上面说的那样吗?

再次谢谢各位了,我把自己成功的弄蒙了
Gloveing 2012-09-18
  • 打赏
  • 举报
回复
好吧,解释一下:
hanoi(n-1,one,three,two);//借助第二根把第一根上的 n-1 个盘子移动到第三根上
move(one,three);//把第一根上,最下面的一个(最大的)直接移动到第三根上
hanoi(n-1,two,one,three);//借助第三根把第二根上的 n-1 个盘子移动到第1根上
Gloveing 2012-09-18
  • 打赏
  • 举报
回复
hanoi(n-1,one,three,two);
move(one,three);
hanoi(n-1,two,one,three);
-------------------
对于递归,你要逆向分析
如果只剩一个盘子、2个的时候、、、该怎么移动,一下子就清楚了
yisikaipu 2012-09-18
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]两位兄弟,能不能加qq啊 我的qq是 1114379246 我这个问题钻到牛角尖了,只要一点点提醒我就能出来了,谢谢了,这个问题我想了好久了[/Quote]

#1楼的提醒不只一点点了 :)

我敢说大多数人初见汉诺塔递归都会觉得不可思议

而同样,初见阶乘的递归却不觉得奇怪

因为前者太反直觉了

SMouse鱼骨头 2012-09-18
  • 打赏
  • 举报
回复
两位兄弟,能不能加qq啊 我的qq是 1114379246 我这个问题钻到牛角尖了,只要一点点提醒我就能出来了,谢谢了,这个问题我想了好久了
赵4老师 2012-09-18
  • 打赏
  • 举报
回复
“给定一个小点的输入,完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门!
递归函数关注以下几个因素
·退出条件
·参数有哪些
·返回值是什么
·局部变量有哪些
·全局变量有哪些
·何时输出
·会不会导致堆栈溢出
dzweather 2012-09-18
  • 打赏
  • 举报
回复
要把这个定义看清楚


本想写写,发现百度上写得比我详细多了,你参考一下吧:
先看hanoi(1, one, two, three)的情况。这时直接将one柱上的一个盘子搬到three柱上。注意,这里one柱或three柱到底是A、B还是C并不重要,要记住的是函数第二个参数代表的柱上的一个盘被搬到第四个参数代表的柱上。为方便,将这个动作记为:
one =》three

再看hanoi(2, one, two, three)的情况。考虑到hanoi(1)的情况已经分析过了,可知这时实际上将产生三个动作,分别是:
one =》two
one =》three
two =》three
很显然,这实际上相当于将one柱上的两个盘直接搬到three柱上。

再看hanoi(3, one, two, three)的情况。分析
hanoi(2, one , three, two)
one =》three
hanoi(2, two, one, three)
即:先将one柱上的两个盘搬到two柱上,再将one柱上的一个盘搬到three柱上,最后再将two柱上的两个盘搬到three柱上。这不就等于将one柱上的三个盘直接搬到three柱上吗?

运用归纳法可知,对任意n,
hanoi(n-1, one , three, two)
one =》three
hanoi(n-1, two, one, three)
就是先将one柱上的n-1个盘搬到two柱上,再将one柱上的一个盘搬到three柱上,最后再将two柱上的n-1个盘搬到three柱上。这就是我们所需要的结果!

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧