Javascript 递归算法如何适用于河内塔?
这是我在一本书中解释递归的代码。问题是我不理解该计划采取的步骤:Javascript 递归算法如何适用于河内塔?,javascript,recursion,towers-of-hanoi,Javascript,Recursion,Towers Of Hanoi,这是我在一本书中解释递归的代码。问题是我不理解该计划采取的步骤: var hanoi = function(disc,src,aux,dst) { if (disc > 0) { hanoi(disc - 1,src,dst,aux); document.write("Move disc " + disc + " from " + src + " to " + dst + "<br />"); hanoi(disc - 1
var hanoi = function(disc,src,aux,dst) {
if (disc > 0) {
hanoi(disc - 1,src,dst,aux);
document.write("Move disc " + disc + " from " + src + " to " + dst + "<br />");
hanoi(disc - 1,aux,src,dst);
}
};
hanoi(3,"src","aux","dst");
有人能一步一步地把它分解吗?这对我很有帮助。我已经弄明白了。分解后,代码按如下方式运行:
var write = function(string) {
document.write(string);
}
var i = 0;
var hanoi = function(disc,src,aux,dst) {
if (disc > 0) {
hanoi(disc - 1,src,dst,aux);
write("Move disc " + disc + " from " + src + " to " + dst + "<br />");
hanoi(disc - 1,aux,src,dst);
}
};
hanoi(3,"src","aux","dst");
/*
hanoi(3,"src","aux","dst");
if (disc > 0) {
hanoi(2,'src','dst','aux');
if (disc > 0) {
hanoi(1,'src','aux','dst');
if (disc > 0) {
hanoi(0,'src','dst','aux');
END
write("Move disc " + 1 + " from " + src + " to " + dst + "<br />");
hanoi(0,'aux','src','dst');
END
}
write("Move disc " + 2 + " from " + src + " to " + dst + "<br />");
hanoi(1,'dst','src','aux');
if (disc > 0) {
hanoi(0,'src','dst','aux');
END
write("Move disc " + 1 + " from " + src + " to " + dst + "<br />");
hanoi(0,'aux','src','dst');
END
}
}
write("Move disc " + 3 + " from " + src + " to " + dst + "<br />");
hanoi(2,'aux','src','dst');
if (disc > 0) {
hanoi(1,'aux','dst','src');
if (disc > 0) {
hanoi(0,'src','dst','aux');
END
write("Move disc " + 1 + " from " + src + " to " + dst + "<br />");
hanoi(0,'aux','src','dst');
END
}
write("Move disc " + 2 + " from " + src + " to " + dst + "<br />");
hanoi(1,'src','aux','dst');
if (disc > 0) {
hanoi(0,'src','dst','aux');
END
write("Move disc " + 1 + " from " + src + " to " + dst + "<br />");
hanoi(0,'aux','src','dst');
END
}
}
}
*/
var write=函数(字符串){
document.write(字符串);
}
var i=0;
var hanoi=功能(磁盘、src、辅助、dst){
如果(光盘>0){
河内(disc-1、src、dst、aux);
写入(“将光盘”+光盘+”从“+src+”移动到“+dst+”
);
河内(disc-1、辅助、src、dst);
}
};
河内(3,“src”、“aux”、“dst”);
/*
河内(3,“src”、“aux”、“dst”);
如果(光盘>0){
河内(2,'src','dst','aux');
如果(光盘>0){
河内(1,'src','aux','dst');
如果(光盘>0){
河内(0,'src','dst','aux');
结束
写入(“将光盘“+1+”从“+src+”移动到“+dst+”
);
河内(0,'aux','src','dst');
结束
}
写入(“将光盘“+2+”从“+src+”移动到“+dst+”
”);
河内(1,'dst','src','aux');
如果(光盘>0){
河内(0,'src','dst','aux');
结束
写入(“将光盘“+1+”从“+src+”移动到“+dst+”
);
河内(0,'aux','src','dst');
结束
}
}
写入(“将光盘“+3+”从“+src+”移动到“+dst+”
”);
河内(2,'aux','src','dst');
如果(光盘>0){
河内(1,'aux','dst','src');
如果(光盘>0){
河内(0,'src','dst','aux');
结束
写入(“将光盘“+1+”从“+src+”移动到“+dst+”
);
河内(0,'aux','src','dst');
结束
}
写入(“将光盘“+2+”从“+src+”移动到“+dst+”
”);
河内(1,'src','aux','dst');
如果(光盘>0){
河内(0,'src','dst','aux');
结束
写入(“将光盘“+1+”从“+src+”移动到“+dst+”
);
河内(0,'aux','src','dst');
结束
}
}
}
*/
关于这一点,最令人困惑的部分是可视化第一个递归循环的结束。只有当disc==0时,disc==3的语句才会最终被写入。也许解决河内塔楼问题的最简单方法是这样的:
hanoi(3, src, aux, dest)
hanoi(2, src, dest, aux)
hanoi(1, src, aux, dest)
hanoi(0, src, dest, aux) // no op
print "Move 1 from src to dest"
hanoi(0, aux, src, dest) // no op
print "Move 2 from src to aux"
hanoi(1, dest, src, aux)
hanoi(0, dest, aux, src) // no op
print "move 1 from dest to aux"
hanoi(0, src, dest, aux) // no op
print "move 3 from src to dest"
hanoi(2, aux, src, dest)
hanoi(1, aux, dest, src)
hanoi(0, aux, src, dest) // no op
print "Move 1 from aux to src"
hanoi(0, dest, aux, src) // no op
print "Move 2 from aux to dest"
hanoi(1, src, aux, dest)
hanoi(0, src, dest, aux) // no op
print "move 1 from src to dest"
hanoi(0, aux, src, dest) // no op
要将x
盘从销钉A移动到销钉C,使用销钉B作为“辅助”销钉:
x-1
盘从销钉A移动到销钉Bx
第四张光盘从销钉A移动到销钉C(无需辅助销钉,因为您只移动一张光盘)x-1
盘从销钉B移动到销钉Cx
光盘,必须移动x-1
光盘。您可以使用相同的功能移动这些x-1
光盘,只需切换哪些销钉是源销钉、目的销钉和辅助销钉。这就是为什么《河内之塔》是递归的一个常见例子,这就是你需要在一个问题中看到的模式,以便让递归为你工作。当然,它不必是“移动x-1
discs”,也可以是类似“列出此子文件夹”的内容。树(比如带有子文件夹的目录等)是递归的另一个亮点。与其他作业一样,为了在项目上执行作业,您可能需要在子项目上执行相同的作业
现在,为了得到有用的递归,您需要一个“基本情况”——递归将停止的条件。如果不这样做,代码将永远运行(或者至少直到内存耗尽或溢出调用堆栈)。这里的基本情况发生在x==0
时(因为移动0个光盘意味着你什么也不做,因为函数的核心是if
)。也可能是当x==1
时,因为这样就不必递归,但是在每次hanoi
调用之前额外的if
会增加一些噪音(递归解决方案的主要好处是它的简单性)。无论如何,当x==0
时,函数将返回,而不执行任何操作。调用它的函数(它有x==1
)现在可以继续做它的事情了——在本例中,说“将光盘1从src移动到dest”,然后在参数切换的情况下再次调用hanoi
函数
流程有点像这样:
hanoi(3, src, aux, dest)
hanoi(2, src, dest, aux)
hanoi(1, src, aux, dest)
hanoi(0, src, dest, aux) // no op
print "Move 1 from src to dest"
hanoi(0, aux, src, dest) // no op
print "Move 2 from src to aux"
hanoi(1, dest, src, aux)
hanoi(0, dest, aux, src) // no op
print "move 1 from dest to aux"
hanoi(0, src, dest, aux) // no op
print "move 3 from src to dest"
hanoi(2, aux, src, dest)
hanoi(1, aux, dest, src)
hanoi(0, aux, src, dest) // no op
print "Move 1 from aux to src"
hanoi(0, dest, aux, src) // no op
print "Move 2 from aux to dest"
hanoi(1, src, aux, dest)
hanoi(0, src, dest, aux) // no op
print "move 1 from src to dest"
hanoi(0, aux, src, dest) // no op
您是否阅读了可能的副本?另外:可能的副本请检查我的答案,并详细说明步骤。如果您想问另一个问题,请在实际的新问题中提问,因为没有人会知道在您的答案中查找问题DHere是java中完整的最短源代码