迷宫求解器的递归

时间:2012-09-29 22:04:45

标签: java recursion stack-overflow maze

该项目是使用递归和树来编写Java中的迷宫求解器(我使用自己的链表,不确定它是否是树,但我不介意)。

讲师从不解释任何事情,所以我在网上获得了所有的知识。我的递归方法有问题,我不知道该怎么做,因为我找不到一个与我的项目有关的例子

在我的链接列表中,我有指向右侧,左侧,底部和顶部的节点的链接。如果右边有墙,则链接为空。我还在链接列表wallRightwallLeftwallBottomwallTop中设置了布尔值,以查看是否存在右侧的墙。因此,如果右侧有一堵墙,则“右侧”链接将为空,wallRight将为真。

我也使用标签作为图像,所以如果我登陆某个地方,图像会显示出来。我做了一个方法,如果我在位置1,它会使标签1显示,所以在递归方法中我使用int pos来知道要显示的标签。

现在我的递归方法遇到了麻烦。我尝试了两种方法,但都没有工作。以下是两者:

public boolean move(Maze rigting,int pos) // Righting = direction
{
   if(rigting.goal == true)
       return true; //BASE CASE - tests if it is on the goal node

   else if(rigting.wallR != true) //checks if there is a wall on the right
   {
       pos += 1;
       move(rigting.right, pos); //moves right

       showLabel(pos);
       return true;
   }

   else if(rigting.wallD != true) //checks if there is a wall below
   {
       pos += 10;
       move(rigting.down, pos); //moves down

       showLabel(pos);
       return true;
   }

   else if(rigting.wallL != true) //checks if there is a wall on the left
   {
       pos -= 1;
       move(rigting.left, pos); //moves left

       showLabel(pos);
       return true;
   }

   else if(rigting.wallU != true) //checks if there is a wall above
   {
       pos -= 10;
       move(rigting.up, pos); //moves up

       showLabel(pos);
       return true;
   }

   return false; //I know this return is incorrect, but it won't run without one
 }

public boolean move(Maze rigting,int pos) //Righting = direction
{
    if(rigting.goal == true)
        return true;

    return (rigting.wallR != true) ? move(rigting.right, pos += 1) : false ||
    (rigting.wallD != true) ? move(rigting.down, pos += 10) : false ||
    (rigting.wallL != true) ? move(rigting.left, pos -= 1) : false ||
    (rigting.wallU != true) ? move(rigting.up, pos -= 10) : false;
}

这两个都给出了stackoverflow异常......
我认为我的错误是,如果右边有一堵墙,那么右边的链接是null。如果我能以某种方式确保没有任何链接null,那么我就不需要布尔wallRight等,但我不知道如何实现它。

如果你能把我送到正确的方向,我真的很感激!我只需要在10月10日交付这个项目,所以如果我完全错了,我不介意重新开始!

1 个答案:

答案 0 :(得分:1)

由于这是你的作业,我不会在这里给你一个解决方案,但有一些提示。

  1. 您的第一个解决方案不会考虑后续调用move()的结果,因此只有达到目标(意外)时递归才会结束。
  2. 在您的第二个解决方案中,您会考虑结果,但不准备用于循环移动的情况。您需要标记已访问过的节点并在那里中断(返回值为false)。
  3. 对于递归,最好从中断条件开始(就像你一样),然后实现一个简单的情况(例如总是向右)。在管理简单案例后,您可以添加其他(分支)