汉诺塔的递归算法很好理解,为什么这个非递归就这么难理解?

bright5 2001-11-07 03:05:29
一般递归算法都可以用栈转化成非递归算法,譬如求阶乘等,都比较好理解。汉诺塔的递归算法也好理解,但转化成非递归我理解起来就是不甚了了,似是而非。请高手们帮我指点指点,讲解讲解!
汉诺塔的递归算法简洁明了,很好理解,程序如下
PROCEDURE Hanoi(n:integer; x,y,z:CHAR);
BEGIN
IF n=1
THEN move (1,x,z)
ELSE BEGIN
hanoi(n-1,x,z,y);
move (n,x,z);
hanoi(n-1,y,x,z);
END;
END;
其改为非递归算法后就让我比较头疼了,如下:
PROCEDURE Hanoi(n:integer; x,y,z:CHAR);
CONST m=100;
TYPE snode=RECORD
n:integer;
x,y,z:char
END;
VAR S:ARRAY[1..m] OF snode;
H,t: integer; a,b,c,k: char;
G:0..1;
BEGIN
t:=0; a:=x; b:=y; c:=z; H:=n;
REPEAT
IF H=1
THEN BEGIN
G:=0; move(1,a,c)
END
ELSE BEGIN
t:=t+1; s[t].n:=H;
s[t].x=a; s[t].y:=b;
s[t].z:=c; H:=H-1;
k:=c; c:=b;
b:=k; G:=1
END;
IF (G=0) AND (T>0)
THEN BEGIN
G:=1; H:=s[t].n;
a:=s[t].x; b:=s[t].y;
c:=s[t].z; t:=t-1;
move(H,a,c); H:=H-1;
k:=a; a:=b; b:=k
END
UNTIL (G=0) AND (t=0)
END;
(注:算法中G是标志位,move(H,a,c)过程是将H号盘从钢针a移到钢针c)
...全文
1687 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
blue_stone 2001-12-28
  • 打赏
  • 举报
回复
只不过只做了一些本来可以让计算机做的事情罢了!
MadLee 2001-11-29
  • 打赏
  • 举报
回复
改成C++的。
struct snode {
int n,
char x, y, z;
};

void Hanoi(const snode& v) {
stack<snode> s;
snode v(x);

while(true) {
if(v.n == 1)
move(v.a, v.c);
else {
s.push(v);
--v.n;
swap(v.c, v.b);
}

if(s.empty())
break;
else {
v = s.top();
s.pop();
move(a, c);
--v.n;
swap(v.a, v.b);
}
}
}

MadLee 2001-11-29
  • 打赏
  • 举报
回复
改成C++的。
struct snode {
int n,
char x, y, z;
};

void Hanoi(const snode& v) {
vector<snode> s;
snode v(x);

while(true) {
if(v.n == 1)
move(v.a, v.c);
else {
s.push_back(v);
--v.n;
swap(v.c, v.b);
}
if(s.empty())
break;
if(s.empty()) {
v = s.back();
s.pop_back();
move(a, c);
--v.n;
swap(v.a, v.b);
}
}
}

其实所谓的非递归就是自己管理栈而已。
plizi 2001-11-29
  • 打赏
  • 举报
回复
关注
bright5 2001-11-21
  • 打赏
  • 举报
回复
笑面虎说得好,其实我已经理解了,确实是知其然,也知所以然了
Smile_Tiger 2001-11-21
  • 打赏
  • 举报
回复
为什么递归好理解?那是因为你理解时没有去考虑堆栈方面的问题,堆栈的问题已经由编译器去解决了,你也不需要去理解,只需要考虑递归这一高层次的问题。

现在你要去实现非递归,那么堆栈的问题编译器不能帮你了,你必须亲自去了解堆栈的问题。

所以你的问题在于没有弄清楚堆栈的问题。
longbinchen 2001-11-21
  • 打赏
  • 举报
回复
这个问题我觉得有意思。我在学方程式的时候,也是觉得用方程解应用题很好理解的,
但是如果仅仅用算式来解应用题,那就难得多了。这里面的道理是不是一样的?
bright5 2001-11-20
  • 打赏
  • 举报
回复
续一下!
7 2001-11-15
  • 打赏
  • 举报
回复
学过“编译原理”么?
对理解这个问题很有帮助
rightyeah 2001-11-15
  • 打赏
  • 举报
回复
我也写了一个,你看如何(没有调试过,刚写的)
Hanoi(int level,int a,int b,int c)
{ int isMove;
if (level==1)
move(level,a,c);
pushtostack(level,a,b,c,0);
while (!emptystack())
{
popfromstack(&level,&a,&b,&c,&isMove);
if(isMove || level==1)
move(level,a,c);
else
{
pushtostack(level-1,b,a,c,0)
pushtostack(level,a,b,c,1);
pushtostack(level-1,a,c,b,0);
}
}
}
move(level,from,to)
{
cout<<"move disk "<<level<<" from "<<from<<" to "<<to<<"."<<endl;
}
bright5 2001-11-15
  • 打赏
  • 举报
回复
还有人吗
bright5 2001-11-14
  • 打赏
  • 举报
回复
续一下!
bright5 2001-11-14
  • 打赏
  • 举报
回复
讨论讨论
Jazzlover 2001-11-14
  • 打赏
  • 举报
回复
没有办法吧?!!
bright5 2001-11-13
  • 打赏
  • 举报
回复
没人哪?
bright5 2001-11-11
  • 打赏
  • 举报
回复
我已经搞清了:))
其实递归实行的结果就是非递归,从这一层往下一层,再从下一层往下下一层,这样层层调用,直至终极那一层,然后再回到上一层。。。。这样慢慢遍历,就好像一个人在游荡一样
人们有了递归思想,可是机器在处理时还是用非递归的。其实都一样,就是从这一层往下一层走后终究要回来,回来之后还要处理这一层的数据,所以要把这一层的参数要暂时保存,好比“保护现场”,而这种保护是经常的,所以要设一个栈!
搞清了!也不知道当年的数据结构怎么学的就过来了。
不过我觉得这个思想得好好理解一下,递归是很好理解,有人性,可是理解一下非递归就更好的理解递归了。
q1415926 2001-11-11
  • 打赏
  • 举报
回复
呵呵,递归算法本来就比非递归好理解,什么问题都是
bright5 2001-11-10
  • 打赏
  • 举报
回复
up一下
sharpmark 2001-11-10
  • 打赏
  • 举报
回复
up + 学习一下
dahaidao 2001-11-10
  • 打赏
  • 举报
回复
学习一下。
加载更多回复(8)

33,006

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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