Java 如何用河内塔调用递归
我正在努力解决河内塔的问题;我写了这段代码:Java 如何用河内塔调用递归,java,recursion,towers-of-hanoi,Java,Recursion,Towers Of Hanoi,我正在努力解决河内塔的问题;我写了这段代码: public class TowersOfHanoi { public static void main(String[] args) { move(5, 1, 3); } public static void move(int disks, int from, int to) { if (disks > 0) { int other = 6 - from - to; // s
public class TowersOfHanoi {
public static void main(String[] args) {
move(5, 1, 3);
}
public static void move(int disks, int from, int to) {
if (disks > 0) {
int other = 6 - from - to; // sum of index 1+2+3=6
System.out.println("Move disk from peg " + from + " to " + to);
move(disks - 1, from, other);
move(disks - 1, other, to);
}
}
}
但结果是错误的。我书中的解决方案是
public class TowersOfHanoi {
public static void main(String[] args) {
move(5, 1, 3);
}
public static void move(int disks, int from, int to) {
if (disks > 0) {
int other = 6 - from - to; // sum of index 1+2+3=6
move(disks - 1, from, other);
System.out.println("Move disk from peg " + from + " to " + to);
move(disks - 1, other, to);
}
}
}
为什么会这样?我无法理解这些表达的顺序:
- 首先运行
System.out.println()
- 然后运行
move(磁盘-1,from,other)
- 现在它再次运行
,或者运行System.out.println()
李>move(disks-1,other,to)
什么时候重新启动块代码?Thanx.正确的解决方案是:
println
语句另一方面,在错误的解决方案中,您试图做的是在移动堆叠在其上的所有光盘之前移动底部光盘,这是无效的移动。河内塔的工作方式是-:
因此,我们有
n
磁盘和3个peg,我们希望将放置在第一个peg(源peg)中的磁盘移动到第三个peg(目标peg);在这种情况下,递归的概念是:
n
)上方的n-1
,从第一个peg移动到第二个peg(备用peg),因为我们希望为最大的磁盘腾出空间,并能够将其放入第三个peg。这是移动(磁盘-1,从,其他)的第一句话move代码>
System.out.println(“将磁盘从peg+从+”移动到“+到”)代码>
n-1
磁盘从第二个peg递归地移动到第三个,以便在第三个peg中重新创建塔,最后一句移动(磁盘-1,其他,移动到)代码>
该算法适用于奇偶
n
磁盘,因为它是一个通用的求解过程,显然,步骤将根据磁盘的初始数量而变化。可能调试器将帮助您了解递归的工作原理。只需在println语句中打印disks
值,以更好地理解整个序列。我已经试着理解您的算法一个多小时了,但我有一些问题:在第一个递归n-1
磁盘是第一个peg顶部的较小磁盘?或者我必须把上面的第一个磁盘看作是<代码> n<代码>,其他的作为代码> n-1 < /代码>,直到底部最大的磁盘为止。因此,最上面或最小的磁盘是1,而最下面(最大)的磁盘是n。所以在第一步中,我们得到了第一个顶部的n-1磁盘(编号从1到n-1)。然后将第n个(底部最大的)放在Ok位置,这样,如果在第一步中有n=5个磁盘,我将选择4个磁盘(disk1-disk2-disk3-disk4),其中disk1最小?。是的,您必须在第一步中移动磁盘1、磁盘2、磁盘3、磁盘4(n-1)磁盘。但这一步是递归调用,它肯定会将所有磁盘(1-4)放在PEG2上。如果你不能理解它,举一个小例子。对于n=1,这是微不足道的。对于n=2,您已经将上述n-1个磁盘,即磁盘1放置到第二个peg,将磁盘1移动到第三个peg,然后将第二个磁盘移动到第三个peg。对于n=3,在第一步中调用递归将递归地移动n-1个磁盘,即磁盘1和磁盘2。然后必须将第三个磁盘移动到第三个peg(即打印移动),然后再次将n-1个磁盘从第二个peg移动到第三个peg(这将通过递归完成)。信任递归为您工作。为什么?如果你想知道n个磁盘和3个PEG需要多少步,那么它就是$2^{n}-1$。这是由于递归方程$T(n)=T(n-1)+1+T(n-1)$或$T(n)=2T(n-1)+1$,求解它。您还可以修改方法以返回int(这将给您提供步骤数)。假设T(n)作为与算法时间复杂度相关的访问数,第一个T(n-1)表示第一步,+1表示打印步骤,第二个T(n-1)表示最后一步,对吗?是的。这是正确的。好。我不希望解释我上面写的内容,你完全理解。好的,请你解释一下你是如何从T(n)=2T(n-1)+1得到2^{n}-1的?我想这会帮助你理解整个解决方案。这里给出了非常详细的解释。
public class TowersOfHanoi {
public static void main(String[] args) {
int first = 1, second = 2, third = 3;
int disk = 5; // or take user input
move(disk, first, third);
}
public static void move(int disks, int first, int second, int third) {
if (disks > 0) {
move(disks - 1, first, third, second); // source = first, dest = second
System.out.println("Move disk from peg " + first+ " to " + third);
move(disks - 1, second, first, third); // source = second, dest = third
}
}
}