Java 递归问题

Java 递归问题,java,recursion,stack,Java,Recursion,Stack,我在创建这个递归方法时遇到问题。该方法需要将对象添加到堆栈中 注: 这是一个路径查找项目 getNextBird()从bird对象内的bird队列轮询。如果队列为空,它将返回null;如果它不是空的,它将返回队列中的下一只鸟 我根本不能使用任何循环。(如果可以的话,那就容易了。) 堆栈中的最后一个元素必须是Bird“end”。但是,如果代码运行良好,则应该递归执行 我的问题是,有一种边缘情况,检查碰到了一堵墙,getNextBird变为null(在本例中为对象bird),我想从堆栈中弹出最新的对

我在创建这个递归方法时遇到问题。该方法需要将对象添加到堆栈中

注: 这是一个路径查找项目

getNextBird()
从bird对象内的bird队列轮询。如果队列为空,它将返回null;如果它不是空的,它将返回队列中的下一只鸟

我根本不能使用任何循环。(如果可以的话,那就容易了。) 堆栈中的最后一个元素必须是Bird“end”。但是,如果代码运行良好,则应该递归执行

我的问题是,有一种边缘情况,检查碰到了一堵墙,
getNextBird
变为null(在本例中为对象bird),我想从堆栈中弹出最新的对象。我将得到StackOverflow错误或EmptyCollection错误

private static boolean recurse(Stack<Bird> path, Bird current, Bird end) 
{
    Bird bird = null;
    if (current != null) {
        bird = current.getNextBird();
        if (bird != null) {
            path.push(current);
            recurse(path, bird, end);
            return true;
        }
    }
    return false;
}

好的,有一件事我看到您在递归中传递了参数
end
,但从未使用过

递归的一个关键点是有一个控制语句,它将导致递归中断并返回正确的东西或什么也不返回。您随机返回了true和false(或者可能存在逻辑),这不会给执行路径添加任何值

那么,让我们用另一种方式来做:

  • 除非需要,否则不要在堆栈中推送任何内容,这样只有在打印时才会弹出。需要推入堆栈的第一只鸟是与表达式
    (current==end)
    匹配的最终鸟
  • 如果该鸟没有返回到前一只鸟,则表明该路径被阻塞。现在,为了与此相匹配,在步骤1中,如果
    (current==end)
    将某些内容返回给前一只鸟,表明找到了最后一只鸟,并将其与链中的每只鸟一起传递给第一只鸟
  • 伪代码:

    recursive(stack, current, end)
    {
        if(current == end){
            stack.push(current); //push the final bird
            return true; //indication that final is found
        }
        else if(current.getNext() != null){
            result = recurse(stack, current.getNext(), end); //recurse
            if(result == true)
              stack.push(current); // using indication from the chain
    
            return result; 
        }
    
        return false;
    }
    

    什么是Bird数据结构?你的输入数据是什么。也许你创造了某种循环,一次又一次地去看同一只鸟?。。。。在中间添加Soal.Out.PrtLn(鸟)是有用的。你能提供一个堆栈跟踪和一个边缘情况的例子吗?@ MST它不会一遍遍地循环同一个鸟。你怎么称呼这个方法?向我们显示输入数据。什么是bird,什么在
    堆栈中?更改recurse(path,path.peek(),end);递归(路径、鸟、结束);这是真的,你是对的!但我的问题是,我将如何推动,并弹出堆栈。由于堆栈在该方法中不应变为空,因此它只应删除不需要的bird对象。是什么使bird不需要?因此,如果bird队列中的下一个bird(位于每个bird对象内,使用getNextBird调用它),在未到达最终bird的情况下变为null,然后从堆栈中移除该特定bird对象。另外,您在代码中使用的包装器的键盘快捷键是什么?
    
    public class Bird
    {
      public static final int N  = 0;
      public static final int NE = 1;
      public static final int E  = 2;
      public static final int SE = 3;
      public static final int S  = 4;
      public static final int SW = 5;
      public static final int W  = 6;
      public static final int NW = 7;
    
      private static final String [] directions = {"N ", "NE", "E ", "SE", "S ", "SW", "W ", "NW"};
    
      private String name;
      private int direction;
      private Queue<Bird> queue;
    
      public Bird(int row, int column, int direction)
      {
        this.name = "Row/Column [" + row + "][" + column + "]";
        this.direction = direction;
      }
    
      public void setBirdQueue(Queue<Bird> queue)
      {
        this.queue = queue;
      }
    
      public String toString()
      {
        return "Location: " + name + ", Direction: " + directions[direction];
      }
    
      public int getDirection()
      {
        return this.direction;
      }
      public Bird getNextBird()
      {
        // write code to return the next Bird from the queue or null if no Birds left.
          return queue.poll();
      }
    }
    
    public class Maze
    {
      private Bird start;
      private Bird end;
    
      public Maze()
      {
        // construct the diagrammed maze
        int MAX_ROW = 5;
        int MAX_COL = 7;
        Bird [][] maze = new Bird[MAX_ROW][MAX_COL];
    
        // row 0
        maze[0][0] = new Bird(0, 0, Bird.S);
        maze[0][1] = new Bird(0, 1, Bird.SW);
        maze[0][2] = new Bird(0, 2, Bird.S);
        maze[0][3] = new Bird(0, 3, Bird.SE);
        maze[0][4] = new Bird(0, 4, Bird.SW);
        maze[0][5] = new Bird(0, 5, Bird.SW);
        maze[0][6] = new Bird(0, 6, Bird.SW);
    
        // row 1
        maze[1][0] = new Bird(1, 0, Bird.S);
        maze[1][1] = new Bird(1, 1, Bird.W);
        maze[1][2] = new Bird(1, 2, Bird.SW);
        maze[1][3] = new Bird(1, 3, Bird.S);
        maze[1][4] = new Bird(1, 4, Bird.N);
        maze[1][5] = new Bird(1, 5, Bird.S);
        maze[1][6] = new Bird(1, 6, Bird.W);
    
        // row 2
        maze[2][0] = new Bird(2, 0, Bird.NE);
        maze[2][1] = new Bird(2, 1, Bird.NW);
        maze[2][2] = new Bird(2, 2, Bird.N);
        maze[2][3] = new Bird(2, 3, Bird.W);
        maze[2][4] = new Bird(2, 4, Bird.SE);
        maze[2][5] = new Bird(2, 5, Bird.NE);
        maze[2][6] = new Bird(2, 6, Bird.E);
    
        // row 3
        maze[3][0] = new Bird(3, 0, Bird.SE);
        maze[3][1] = new Bird(3, 1, Bird.NE);
        maze[3][2] = new Bird(3, 2, Bird.E);
        maze[3][3] = new Bird(3, 3, Bird.NW);
        maze[3][4] = new Bird(3, 4, Bird.NW);
        maze[3][5] = new Bird(3, 5, Bird.E);
        maze[3][6] = new Bird(3, 6, Bird.W);
    
        // row 4
        maze[4][0] = new Bird(4, 0, Bird.N);
        maze[4][1] = new Bird(4, 1, Bird.NE);
        maze[4][2] = new Bird(4, 2, Bird.N);
        maze[4][3] = new Bird(4, 3, Bird.N);
        maze[4][4] = new Bird(4, 4, Bird.NE);
        maze[4][5] = new Bird(4, 5, Bird.W);
        maze[4][6] = new Bird(4, 6, Bird.N);
    
        start = maze[2][0];
        end   = maze[2][6];
    
        // write your code here
        /*snipped the logic for adding the birds in the queue, but I do know that this part is 100% functional on my end*/
      }
    
      public Bird getStart()
      {
        return this.start;
      }
    
      public Bird getEnd()
      {
        return this.end;
      }
    
    }
    
    recursive(stack, current, end)
    {
        if(current == end){
            stack.push(current); //push the final bird
            return true; //indication that final is found
        }
        else if(current.getNext() != null){
            result = recurse(stack, current.getNext(), end); //recurse
            if(result == true)
              stack.push(current); // using indication from the chain
    
            return result; 
        }
    
        return false;
    }