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

Java 递归——如何仅在最后执行操作,java,recursion,data-structures,Java,Recursion,Data Structures,我有一个二进制搜索树,其中每个节点(GameEntryclass)代表一个“游戏”(一个名字/分数对)。树是按名称(而不是分数)组织的。我正在尝试为树编写一个方法来打印其前十名的列表(带有相应的名称)。我考虑递归遍历树,当(且仅当)它是高分时,将节点放入数组(ScoreBoardclass)。它可以工作,除了我的问题是记分板会打印递归过程中的每一步 public void printTopTen() { ScoreBoard board = new ScoreBoard(10); //

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

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

您得到该错误是因为
System.out.println(this.board)
不是
字符串
,并且声明
printTopTen
应返回
字符串

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

public void printTopTen()
{
    ScoreBoard board = new ScoreBoard(10); // new scoreboard with capacity of 10
    printTopTenRecur(this.root, board);
    System.out.println(this.board);
}
这将显示您在
记分板
类的
toString
方法中定义的内容

如果要返回
字符串
,可以这样做:

public String printTopTen()
{
   ScoreBoard board = new ScoreBoard(10); // new scoreboard with capacity of 10
   printTopTenRecur(this.root, board);
   return this.board.toString();
}
  ScoreBoard currentBoard = board.update(node);
  ScoreBoard leftBoard = printTopTenRecur(node.getLeft(), currentBoard);
  ScoreBoard rightBoard = printTopTenRecur(node.getRight(), leftBoard);
但我得到编译时错误void不能转换为字符串

您得到该错误是因为
System.out.println(this.board)
不是
字符串
,并且声明
printTopTen
应返回
字符串

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

public void printTopTen()
{
    ScoreBoard board = new ScoreBoard(10); // new scoreboard with capacity of 10
    printTopTenRecur(this.root, board);
    System.out.println(this.board);
}
这将显示您在
记分板
类的
toString
方法中定义的内容

如果要返回
字符串
,可以这样做:

public String printTopTen()
{
   ScoreBoard board = new ScoreBoard(10); // new scoreboard with capacity of 10
   printTopTenRecur(this.root, board);
   return this.board.toString();
}
  ScoreBoard currentBoard = board.update(node);
  ScoreBoard leftBoard = printTopTenRecur(node.getLeft(), currentBoard);
  ScoreBoard rightBoard = printTopTenRecur(node.getRight(), leftBoard);

我对递归不是很感兴趣,尤其不是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));
}
旁注:
记分板leftBoard=printTopTenRecur(…)
像这样毫无用处,记分板是可变的,所以传递它就足够了

当我想到递归时,我也认为是不可变的,所以我更喜欢
ScoreBoard newBoard=board.update(节点)返回新更新的记分板,如下所示:

public String printTopTen()
{
   ScoreBoard board = new ScoreBoard(10); // new scoreboard with capacity of 10
   printTopTenRecur(this.root, board);
   return this.board.toString();
}
  ScoreBoard currentBoard = board.update(node);
  ScoreBoard leftBoard = printTopTenRecur(node.getLeft(), currentBoard);
  ScoreBoard rightBoard = printTopTenRecur(node.getRight(), leftBoard);

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

我对递归不是很感兴趣,尤其不是它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));
}
旁注:
记分板leftBoard=printTopTenRecur(…)
像这样毫无用处,记分板是可变的,所以传递它就足够了

当我想到递归时,我也认为是不可变的,所以我更喜欢
ScoreBoard newBoard=board.update(节点)返回新更新的记分板,如下所示:

public String printTopTen()
{
   ScoreBoard board = new ScoreBoard(10); // new scoreboard with capacity of 10
   printTopTenRecur(this.root, board);
   return this.board.toString();
}
  ScoreBoard currentBoard = board.update(node);
  ScoreBoard leftBoard = printTopTenRecur(node.getLeft(), currentBoard);
  ScoreBoard rightBoard = printTopTenRecur(node.getRight(), leftBoard);

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

谢谢,您的建议有效。我现在意识到,
println
返回void!在您更正后,我还尝试
返回此.board.toString()
。它可以编译,但我得到运行时错误NoSuchMethodError。再次困惑。谢谢你,你的建议有效。我现在意识到,
println
返回void!在您更正后,我还尝试
返回此.board.toString()
。它可以编译,但我得到运行时错误NoSuchMethodError。再次困惑。谢谢你的不同观点,这给了我很多思考。谢谢你的不同观点,这给了我很多思考。