汉诺塔问题看不懂,请大虾们指点,我是很菜

wangyan8576 2005-12-19 11:08:05
void move (char x,char y)
{
printf("%c-->%c\n",x,y);
}
viod hanoi(int n,char one,char two,char three));//这个递归函数搞不明白,整个就不知道怎么回事
{ if(n==1)move(one,three);
else
{
hanoi(n-1,one,three,two);//在这个语句先不段的调用自己,直到n=1为止?再向下进行?
move(one,three);
hanoi(n-1,two,one,three);
}
}
main()
{
int m;
printf("input the number of disks:");
scanf("%d,&m);
printf("the step to moving %3d disks:\n",m);
hanoi(m,'A','B','C');
}
...全文
191 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
aaafrank 2005-12-20
  • 打赏
  • 举报
回复
其实函数调用,递归(函数的自我嵌套调用)其实主要是通过数据结构中栈的形式实现的,
hanoi(n-1,one,three,two);//oneline
move(one,three);//twoline
hanoi(n-1,two,one,three);//threeline
编译器先调用oneline,并且将twoline的地址存储在栈中.如满足结束条件if释放,并执行地址后的
语句.同时又遇到threeline.这样反复执行直到栈内的地址全部释放完.
move(one,three);其实是调用打印移动步骤的函数.其实也可以改成如下语句.二者等价
std::cout<<one<<"---->"<<three<<std::endl;




Rick_ang 2005-12-20
  • 打赏
  • 举报
回复
思想就是:
如果只省最后一个盘子,那么直接把它移动到目标上
如果是多于一个,那么把其他的借助2移到3
wangyan8576 2005-12-20
  • 打赏
  • 举报
回复
思想明白了些,但对于这个函数还是不太理解:假设输入为3时
viod hanoi(int n,char one,char two,char three)//最初传入的字母顺序是:3,A,B,C
然后第一次调用自己时hanoi(n-1,one,three,two);//改变了two与three的输入顺序:
2,A,C,B
然后再次调用自己hanoi(n-1,one,three,two);//又改变了two与three的输入顺序:
1,A,B,C
此时n==1调用move函数输出,
然后回归:此时把已放上N-1个盘子的two看作是原来的one,把原来的one看作是two,此时two上有n-1个盘子
然后再调用hanoi(n-1,two,one,three);//到此就实在想不下去了。
前面每次调用改变two与three的参数位置,以及hanoi(n-1,two,one,three);这里one与three的位置就真的不明白。
顺便问问:递归函数在不断调用自己时对内存的占用是不是很大,那么在时间上效率如何?
wangyan8576 2005-12-20
  • 打赏
  • 举报
回复
思想我现在明白了,但就是怎么都不理解那个递归函数语句中的技巧。我还是暂且放一下,等下学期上C语言课时再问老师吧,各位大侠跟小弟解释半天,辛苦啦,谢了,现在结帖
Cicinho 2005-12-20
  • 打赏
  • 举报
回复
多做这种递归问题以后就不会生疏了,遇到问题还是最好自己拿只笔跟着走一次。问题就会越来越少了。
useresu 2005-12-20
  • 打赏
  • 举报
回复
cout<<"第"<<n<<"个盘自从"<<a<<"移动到"<<b<<"\n";

useresu 2005-12-20
  • 打赏
  • 举报
回复
mark
Featured 2005-12-20
  • 打赏
  • 举报
回复
cout<<"第<<n<<个盘自从"<<a<<"移动到"<<b<<"\n";
gangzichh 2005-12-20
  • 打赏
  • 举报
回复
printf("第%d个盘自从%c移动到%c\n",n,a,b);
要是用纯的C++代码写出来,
我没有学过C的,真是不好意思的
谢谢了!!!
gangzichh 2005-12-20
  • 打赏
  • 举报
回复
我先说点:高手们,不要老是理论的东西的,最好有代码的
不过楼上的朋友写的不错的
努力吧!
sms88 2005-12-20
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <ctype.h>
#include<stdlib.h>
#include <stdarg.h>

void move(int n,char a,char b)
{
printf("第%d个盘自从%c移动到%c\n",n,a,b);
}

void hanrta(int n,char x,char y,char z)
//把n个盘从x移动到z,用y做辅助柱子
{
if(n==1)
//若只有一个盘,则直接把这个盘从x柱子移动到z柱子
move(1,x,z);
else {
//把n-1个从x移动到y,用z做辅助柱子
hanrta(n-1,x,z,y);
//把第n个盘(最底下的那个盘子了)从x移动到z
move(n,x,z);
//把n-1个盘子,从y移动到z,用x做辅助柱子
hanrta(n-1,y,x,z);
}
}


void main(void)
{
hanrta(2,'x','y','z');
}


cunsh 2005-12-20
  • 打赏
  • 举报
回复
第一步: 先把1的盘子除了最后一个全移到2上,
第二步: 把1上最后一个盘子移到3号盘子。

对.
就是只有这两步.

而第2步"把1上最后一个盘子移到3号盘子。" 是直接移过去的.不用说.
第1步呢. 怎么"把1的盘子除了最后一个全移到2上" ?
这么想. 把"1的盘子除了最后一个"看作全部盘子.就当是没有最下边的盘子.
那个盘子丢了.先不理它.

这就又回到了开始那两步了.
gangzichh 2005-12-20
  • 打赏
  • 举报
回复
谁就不能写个完整的代码,也让我这个初学者来学习一下么?
这个东东还是第一次见过的(我是说用代码)
谢谢了,学习吧!
wangyan8576 2005-12-19
  • 打赏
  • 举报
回复
还是不太明白?
step1:是先借用3把1的盘子除了最后一个全移到2上,然后把1上最后一个盘子移到3号盘子。

step2:再借用3号盘子把2号上的盘子除了最后一个全移到1号,把2号盘子上剩下最后一个再移到1号盘子。
再重复以上两步,只是随着N的减小不会影响已经移到3号盘子上的大碟子
以上是我的猜测,请高手指教
ma100 2005-12-19
  • 打赏
  • 举报
回复
viod hanoi(int n,char one,char two,char three)//借助2,把1移动到3
{
if(n==1)
move(one,three);//只剩下一个,就把1移动到3
else
{
hanoi(n-1,one,three,two);//先借助two把n-1个从one->three

move(one,three);//把剩下的一个从1->3
hanoi(n-1,two,one,three);//把剩下的n-1个借助1从2-〉3
}
}

hanoi(n-1,one,three,two);//借助two把n-1个从one->three

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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