所以我一直在使用堆栈而不是递归来编写河内塔代码,并根据维基百科关于使用迭代解决 ToH 的部分提出了以下逻辑。
if (tower[1].isEmpty() == false && tower[1].peek() != 1) {
if (tower[2].isEmpty() || tower[1].peek() < tower[2].peek()) {
int disk = tower[1].pop();
tower[2].push(disk);
movedSmallest = false;
showTowers();
} else if (tower[3].isEmpty() || tower[1].peek() < tower[3].peek()) {
int disk = tower[1].pop();
tower[3].push(disk);
movedSmallest = false;
showTowers();
}
} else if (tower[2].isEmpty() == false && tower[2].peek() != 1) {
if (tower[3].isEmpty() || tower[2].peek() < tower[3].peek()) {
int disk = tower[2].pop();
tower[3].push(disk);
movedSmallest = false;
showTowers();
} if (tower[1].isEmpty() || (tower[2].isEmpty() == false && tower[2].peek() < tower[1].peek())) {
int disk = tower[2].pop();
tower[1].push(disk);
movedSmallest = false;
showTowers();
}
} else if (tower[3].isEmpty() == false && tower[3].peek() != 1) {
if (tower[2].isEmpty() || (tower[3].isEmpty() == false && tower[3].peek() < tower[2].peek())) {
int disk = tower[3].pop();
tower[2].push(disk);
movedSmallest = false;
showTowers();
} else if (tower[1].isEmpty() || (tower[3].isEmpty() == false && tower[3].peek() < tower[1].peek())) {
int disk = tower[3].pop();
tower[1].push(disk);
movedSmallest = false;
showTowers();
}
}
}
我不想显示完整的代码,因为我不想寻求解决方案或寻求某人来修复它,我只是想要一些关于这如何导致无限循环的指示,因为它似乎是具体在我的代码的这一部分中进行。为了澄清你们可能需要的一些细节,维基百科页面指出,通过迭代,您可以在最小磁盘和非最小磁盘之间交替移动磁盘。如果你要不断地朝一个方向移动最小的圆盘,然后循环回来(想想 A->B->C->A),并在每次移动之间移动另一个圆盘,理论上应该只有一个合法的移动。这就是为什么我在每个变量中都有变量
movedSmallest = false;
,这样程序接下来就会使用小磁盘进行移动。
Enter number of disks
5
[5, 4, 3, 2, 1]
[]
[]
---------------------------------------------------------
[5, 4, 3, 2]
[]
[1]
---------------------------------------------------------
[5, 4, 3]
[2]
[1]
---------------------------------------------------------
[5, 4, 3]
[2, 1]
[]
---------------------------------------------------------
[5, 4]
[2, 1]
[3]
---------------------------------------------------------
[5, 4, 1]
[2]
[3]
---------------------------------------------------------
[5, 4, 1]
[]
[3, 2]
---------------------------------------------------------
[5, 4]
[]
[3, 2, 1]
---------------------------------------------------------
[5]
[4]
[3, 2, 1]
---------------------------------------------------------
[5]
[4, 1]
[3, 2]
---------------------------------------------------------
当我输入 5 时,这是我得到的输出,然后它卡在这里,无限循环。
[5]
[4, 1]
[3, 2]
if (tower[1].isEmpty() == false && tower[1].peek() != 1){
if (tower[2].isEmpty() || tower[1].peek() < tower[2].peek()) {
int disk = tower[1].pop();
tower[2].push(disk);
movedSmallest = false;
showTowers();
} else if (tower[3].isEmpty() || tower[1].peek() < tower[3].peek()) {
int disk = tower[1].pop();
tower[3].push(disk);
movedSmallest = false;
showTowers();
}
}
假设 tower1 是 tower with5,那么它不为空且 peek 不为 1,因此它首先命中 if。 当您查看后续的 if 语句时,它不会命中任何一个,因为没有任何空塔,并且 tower1 - 5 大于 tower2 - 1 和 tower3 - 2。
TLDR 它进入第一个 if 并且什么也不做。因此状态不会改变,并且它会永远执行相同的事情。
因此请检查并找出需要更改的内容。顺便说一句,在这种情况下,您可以尝试将调试日志添加到每个 if 中,并查看它采用的路径以及它被卡住的原因。更好地调试它正在检查 if 的值,以便更好地理解。
祝你好运!