递归 - 如何仅在最后执行操作

时间:2017-03-25 16:15:51

标签: java recursion data-structures

我有一个二叉搜索树,其中每个节点(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 个答案:

答案 0 :(得分:2)

我不是一个非常有趣的递归,特别是它不是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,如下所示:

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

这样printTopTenRecur是一个没有副作用的函数,所以功能正常。

答案 1 :(得分:1)

  

但是我得到编译时错误void无法转换为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);
}

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

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

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