java返回语句

java返回语句,java,data-structures,binary-tree,return,Java,Data Structures,Binary Tree,Return,我有一个关于以下代码的问题 private void printTree(Node node){ if(node==null) return; printTree(node.left); System.out.print(node.data+" "); printTree(node.right); } 我真的不明白“返回”的意思这里有一份声明。若节点为空,代码将不返回任何内容。但是如果没有这一行,编译器将生成一个异常错误。这是一个递归函数(重复调用自身的函数)。

我有一个关于以下代码的问题

private void printTree(Node node){
    if(node==null) return;
    printTree(node.left);
    System.out.print(node.data+" ");
    printTree(node.right);
}

我真的不明白“返回”的意思这里有一份声明。若节点为空,代码将不返回任何内容。但是如果没有这一行,编译器将生成一个异常错误。

这是一个递归函数(重复调用自身的函数)。
返回
的目的是确保它不会永远尝试这样做,从而在从树的底部运行时导致空指针异常

将发生的情况是,第一次使用节点(通常,但不总是根节点)调用此函数时,它将首先打印出该节点的左子树,然后是节点本身的值,然后是该节点的右子树

它打印子树的方式是使用该子树的顶级节点调用自己。这是优雅地处理递归结构的一种非常常见的方法

null
的测试是这样的,即当它到达一个节点时,该节点在您正在检查的特定一侧(左侧或右侧)没有子节点,在树的各个级别上的搜索就会停止

举例来说,假设您有以下树(大写字母及其数字是实数节点,数字是其值,
==
标记为空):

下面是使用
A
调用函数时将发生的情况

You call the function (level 0) with A.
  The function will call itself (level 1) with B (A left).
    The function will call itself (level 2) with D (B left).
      The function will call itself (level 3) with null (D left).
        The function will return to level 2.
      The function will print out 11 from D.
      The function will call itself (level 3) with null (D right).
        The function will return to level 2.
      The function will return to level 1.
    The function will print out 14 from B.
    The function will call itself (level 2) with null (B right).
      The function will return to level 1.
    The function will return to level 0.
  The function will print out 26 from A.
  The function will call itself (level 1) with C (A right).
    The function will call itself (level 2) with null (C left).
      The function will return to level 1.
    The function will print out 84 from C.
    The function will call itself (level 2) with E (C right).
      The function will call itself (level 3) with null (E left).
        The function will return to level 2.
      The function will print out 99 from E.
      The function will call itself (level 3) with null (E right).
        The function will return to level 2.
      The function will return to level 1.
    The function will return to level 0.
  The function will return to you.
结果是它打印出了序列
DBACE
,在排序树中,该序列是按排序顺序
(11、14、26、84、99)
排列的元素


或者,如果您不想费心阅读我上面大量的解释,可以选择一个更简单的版本:

             A26                Level 0
              |
       +------+------+
       |             |
      B14           ===         Level 1
       |
    +--+--+
    |     |
   ===   ===                    Level 2

You call the function (level 0) with A.
  The function will call itself (level 1) with B (A left).
    The function will call itself (level 2) with null (B left).
      The function will return to level 1.
    The function will print out 14 from B.
    The function will call itself (level 2) with null (B right).
      The function will return to level 1.
    The function will return to level 0.
  The function will print out 26 from A.
  The function will call itself (level 1) with null (A right).
    The function will return to level 0.
  The function will return to you.

在这种情况下,您将得到
BA
(14,26)

任何声明为void的方法都不会返回值。它不需要包含return语句,但可以这样做。在这种情况下,可以使用return语句从控制流块中分支并退出该方法,其使用方式如下:

return;
来自Java语言规范:

14.17返回声明

return语句将控件返回给 方法的调用方(§8.4,§15.12) 或建造商(§8.8,§15.9)

没有表达式的返回语句 必须包含在 使用 关键字void,不返回任何值 (§8.4),或在 建造商(§8.8)。编译时 返回语句时发生错误 出现在实例初始值设定项中 或静态初始值设定项(§8.7)。A. 不带表达式的return语句 尝试将控制权转移到 方法或构造函数的调用程序 这就包含了它。准确地说,一个 不带表达式的return语句 总是突然完成,原因是什么 是没有价值的回报

带有表达式的返回语句 必须包含在方法中 声明返回的声明 值(§8.4)或编译时错误 发生。表达式必须表示一个 某些类型T或a的变量或值 发生编译时错误。T型 必须可转让(§5.2)给 方法的已声明结果类型,或 发生编译时错误


在我看来,如果节点为null,它将在抛出NullReferenceException之前退出函数调用。因为它是递归的,所以它需要它通过“后退”到其父节点来处理树的节点(叶)。

您还可以返回,这样您就不会调用node.data。请记住,如果其为null,则不能对其调用实例方法。

'return'语句在此处充当递归调用的终止条件。每个递归方法都需要一个修正的终止条件,否则它将进入一个无限循环

if(node==null) return;
此语句基本上表示您已到达叶节点(分支的最后一个节点)并终止光标的任何进一步移动


删除return时出现的例外情况是,一旦到达leaf节点和statements
printTree(node.left),就没有任何其他节点可以移动
打印树(右节点)无效。

编写此代码的一种不太容易混淆的方法是:

private void printTree(Node node){
    if (node.left != null) {
       printTree(node.left);
    }
    System.out.print(node.data);
    if (node.right != null) {
       System.out.print(" ");
       printTree(node.right);
    }
}

有时很难识别一个没有结束的回报。大多数人习惯于在这里找到它。此外,不返回任何内容的返回也可能令人困惑。更明显的写作方式是:

private void printTree(Node node) { if(node!=null) { printTree(node.left); System.out.print(node.data+" "); printTree(node.right); } } 私有void打印树(节点){ 如果(节点!=null){ 打印树(node.left); System.out.print(node.data+“”); printTree(右节点); } }
所以,简单地说,“如果有一个节点,请访问它”

Return语句通过以下方式易于理解:

没有返回类型的方法不能返回值,而是返回控件


任何可以返回值的方法都可以返回必须与方法的返回类型兼容的值

是编译器给出了错误,还是您在运行时得到了错误?对我来说,问题中给出的版本看起来更清晰,因为递归终止条件很明显。这取决于您的编码风格。有多个返回通常会使其更难阅读。可能并非所有人都同意。这两种方法似乎都是按顺序遍历二叉树的清晰实现:代码不同:您仍然可以得到
NullPointerException
(有时需要!)是的,在调用此方法之前需要进行空值检查。很好,@Don,在堆栈溢出之前,几乎肯定会出现空指针异常(除非堆栈特别小)。修改为修复。
private void printTree(Node node){
    if (node.left != null) {
       printTree(node.left);
    }
    System.out.print(node.data);
    if (node.right != null) {
       System.out.print(" ");
       printTree(node.right);
    }
}
private void printTree(Node node) { if(node!=null) { printTree(node.left); System.out.print(node.data+" "); printTree(node.right); } }