2

メソッド呼び出し自体の後のステートメントはいつ実行されますか?

private void inorderHelper(TreeNode node)
{
    if ( node==null )
        return;
    inorderHelper(node.leftNode);
    System.out.printf("%d", node.data);
    inorderHelper(node.rigthNode);
}

私が見ることができるのは、コード行 inorderHelper(node.leftNode) が node == null まで反復し続け、メソッドが node.data が出力される直前に終了することだけです。再帰がうまくいかなかったと思いますが、見つけることができるすべての例には、再帰呼び出しの後にステートメントがありません。私が知りたいのは、メソッドが戻る前に System.out.printf("%d",node.data) のようなステートメントが実行されるのはいつですか?

4

3 に答える 3

2

メソッドの単一のアクティブ化の観点から考えているようです。再帰呼び出しの状況では、同じメソッドを何度も呼び出すことができます。各呼び出しには、独自のスタック フレームがあります。return は、それが呼び出されたアクティベーションからのみ戻ります。戻ると、別のメソッドによって呼び出されたかのように、制御はそれを呼び出したアクティベーションに戻されます。

再帰呼び出しの後のコードは、各アクティベーションで、呼び出したアクティベーションから戻るとすぐに実行されます。

于 2012-12-18T04:48:02.267 に答える
1

この関数は、左半分がトラバースされるまでバイナリ ツリーを再帰的にトラバースし、データを出力してから、ツリーの右半分をトラバースします。

これは、ツリーのすべてのレベルで同じです。これは、データが出力される前に、任意のレベルでツリーの左半分が出力され、その後に右半分が出力されることを意味します。

この処理方法は、関数が示すように「順序トラバーサル」と呼ばれます。他の方法は、データが最初に印刷される「順序トラバーサル」と、データが最後に印刷される「順序トラバーサルの後」です。ウィキペディアに詳細があります。

よりよく学習するために、デバッガーを使用してステップ実行できます。

類推として、内なる夢が終わるまで各夢が一時停止することを除いて、インセプションを考えてみてください。もう 1 つの違いは、Inception では、外部の Dream が内部の Dream の終了を制御するのに対して、再帰では、外部の呼び出しは、続行する前に、内部の呼び出しが終了するまで待機する必要があることです。

于 2012-12-18T04:36:54.397 に答える
0

これを実行してみてください。良い画像が得られるはずです。

// first call with depth 0
private void inorderHelper(TreeNode node, int depth)
{
  ++depth;
  if ( node==null ) {
    System.out.printf("null node at depth %d", depth);
    return;
  }
  System.out.printf("depth %d data %d before left side", depth, node.data);
  inorderHelper(node.leftNode, depth);
  System.out.printf("depth %d data %d middle", depth, node.data);
  inorderHelper(node.rigthNode, depth);
  System.out.printf("depth %d data %d after right side", depth, node.data);
}
于 2012-12-18T04:59:56.337 に答える