有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java递归如何只在最后执行操作

我有一个二进制搜索树,其中每个节点(GameEntry类)表示一个“游戏”(一个名称/分数对)。树是按名称(而不是分数)组织的。我正在尝试为树编写一个方法来打印其前十名的列表(带有相应的名称)。我考虑递归遍历树,当(并且仅当)它是高分时,将一个节点放入数组(ScoreBoard类)。它可以工作,除了我的问题是记分板会打印递归过程中的每一步

public void printTopTen()
{
    ScoreBoard board = new ScoreBoard(10); // new scoreboard with capacity of 10
    printTopTenRecur(this.root, board);
}

// Auxillary method for printTopTen()
private void printTopTenRecur(GameEntry node, ScoreBoard board)
{
    if (node == null)
        {
            return;
        }
    printTopTenRecur(node.getLeft(), board);
    board.add(node); // adds the node to the scoreboard if it's a high score
    System.out.println(board);
    printTopTenRecur(node.getRight(), board);
}

我唯一能想到的就是在类上创建一个属性(称为board),然后在递归完成后打印出该属性。但是我得到了编译时错误void cannot be converted to String。我不知道还能怎么做

public String printTopTen()
{
    ScoreBoard board = new ScoreBoard(10); // new scoreboard with capacity of 10
    printTopTenRecur(this.root, board);
    return System.out.println(this.board);
}

// Auxillary method for printTopTen()
private void printTopTenRecur(GameEntry node, ScoreBoard board)
{
    if (node == null)
        {
            return;
        }
    printTopTenRecur(node.getLeft(), board);
    board.add(node); // adds the node to the score board if it's a high score
    this.board = board; // assign local board to the board on the tree
    printTopTenRecur(node.getRight(), board);
}

共 (2) 个答案

  1. # 1 楼答案

    我对递归不是很感兴趣,尤其不是it java,主要原因是如果你做得太深,可能会导致堆栈溢出。其他语言处理这个问题,允许将尾部调用隐式转换为while循环(例如scala)

    也就是说,没有返回值的递归对我来说真的很奇怪,而moondaisy的建议解决了你的问题,我宁愿返回分数,而不是依赖字段

    private ScoreBoard printTopTenRecur(GameEntry node, ScoreBoard board){
      if(node == null )
        return board;
    
      board.add(node);
      ScoreBoard leftBoard = printTopTenRecur(node.getLeft(), board);
      ScoreBoard rightBoard = printTopTenRecur(node.getRight(), leftBoard);
    
      return rightBoard;
    }
    
    public void printTopTen(){
        ScoreBoard board = new ScoreBoard(10); // new scoreboard with capacity of 10
        // No need to return anything if you want to just print the result
        System.out.println(printTopTenRecur(this.root, board));
    }
    

    旁注 ScoreBoard leftBoard = printTopTenRecur(...)是非常无用的,因为板是可变的,所以传递它就足够了

    当我认为递归时,我也认为是不可变的,因此我更希望ScoreBoard newBoard = board.update(node);返回一个新的更新记分板,如下所示:

      ScoreBoard currentBoard = board.update(node);
      ScoreBoard leftBoard = printTopTenRecur(node.getLeft(), currentBoard);
      ScoreBoard rightBoard = printTopTenRecur(node.getRight(), leftBoard);
    

    这样,printTopTenRecur是一个没有副作用的函数,因此是一个合适的函数

  2. # 2 楼答案

    But I'm getting the compile time error void cannot be converted to String

    您得到该错误是因为System.out.println(this.board);不是一个String,并且声明printTopTen应该返回一个String

    如果您只想在递归结束时打印电路板,则可以执行以下操作:

    public void printTopTen()
    {
        ScoreBoard board = new ScoreBoard(10); // new scoreboard with capacity of 10
        printTopTenRecur(this.root, board);
        System.out.println(this.board);
    }
    

    这将显示在ScoreBoard类的toString方法中定义的内容

    如果您想返回String,可以这样做:

    public String printTopTen()
    {
       ScoreBoard board = new ScoreBoard(10); // new scoreboard with capacity of 10
       printTopTenRecur(this.root, board);
       return this.board.toString();
    }