Java
 Computer >> コンピューター >  >> プログラミング >> Java

Javaで二分木のインオーダー(中間順)トラバーサルを実行するプログラム

この記事では、二分木におけるインオーダー(中間順)トラバーサルの実装方法について詳しく解説します。インオーダー走査とは、各ノードを「左の部分木 → ノード自身 → 右の部分木」の順番で処理する手法です。つまり、まず左側の部分木をすべて訪問し、その後にノード自体を処理し、最後に右側の部分木を訪れます。

実際の動作例を見てみましょう。

入力(プログラムの実行):

Run the program

期待される出力:

The In-Order traversal of the tree_object is:
5->12->6->1->9->

アルゴリズム

インオーダー走査は、以下の手順で実行します。

  1. 処理を開始する。
  2. ノードのデータ構造を定義したクラスをあらかじめ用意しておく。
  3. クラスの新しいインスタンスを作成する。
  4. 作成したインスタンスを適切な値で初期化する。
  5. インオーダー走査を実行するメソッドを呼び出す。
  6. 結果を表示する。
  7. 処理を終了する。

例1:再帰を使ったインオーダー走査

まずは、もっとも一般的な再帰呼び出しを利用した実装例です。左部分木・ノード・右部分木の順に再帰的に処理することで、シンプルに記述できます。

class Node {
    int item;
    Node left_node, right_node;
    public Node(int key) {
        item = key;
        left_node = right_node = null;
    }
}
public class Tree {
    Node root;
    Tree() {
        root = null;
    }
    void inOrder(Node node) {
        if (node == null)
            return;
        inOrder(node.left_node);
        System.out.print(node.item + "->");
        inOrder(node.right_node);
    }
    public static void main(String[] args) {
        Tree tree_object = new Tree();
        System.out.println("A tree_object object is defined: ");
        tree_object.root = new Node(1);
        tree_object.root.left_node = new Node(12);
        tree_object.root.right_node = new Node(9);
        tree_object.root.left_node.left_node = new Node(5);
        tree_object.root.left_node.right_node = new Node(6);
        System.out.println("The In-Order traversal of the tree_object is: ");
        tree_object.inOrder(tree_object.root);
    }
}

出力結果

A tree_object object is defined:
The In-Order traversal of the tree_object is:
5->12->6->1->9->

例2:スタックを使った非再帰的なインオーダー走査

次に、Stack(スタック)を利用した非再帰(反復的)な実装例を紹介します。再帰を使わないため、深い木構造でもスタックオーバーフローの心配が少なくなるというメリットがあります。

import java.util.Stack;
class Node {
    int data;
    Node left_node, right_node;
    public Node(int item) {
        data = item;
        left_node = right_node = null;
    }
}
class tree {
    Node root;
    void inorder() {
        if (root == null)
            return;
        Stack<Node> temp_stack = new Stack<Node>();
        Node current_node = root;
        while (current_node != null || temp_stack.size() > 0) {
            while (current_node != null) {
                temp_stack.push(current_node);
                current_node = current_node.left_node;
            }
            current_node = temp_stack.pop();
            System.out.print(current_node.data + " ");
            current_node = current_node.right_node;
        }
    }
    public static void main(String args[]) {
        tree tree = new tree();
        System.out.println("A tree_object object is defined: ");
        tree.root = new Node(1);
        tree.root.left_node = new Node(2);
        tree.root.right_node = new Node(3);
        tree.root.left_node.left_node = new Node(4);
        tree.root.left_node.right_node = new Node(5);
        System.out.println("The In-Order traversal of the tree_object is: ");
        tree.inorder();
    }
}

出力結果

A tree_object object is defined:
The In-Order traversal of the tree_object is:
4 2 5 1 3

まとめ

このように、インオーダー走査は「左部分木 → ノード → 右部分木」の順でノードを訪問する手法です。再帰を使えばコードを簡潔に書ける一方、スタックを活用すれば再帰なしで実装でき、大きな木構造にも対応しやすくなります。用途や木のサイズに応じて、適切な方法を選択しましょう。

  1. PythonでN分木の直径を求める方法|DFSを使った実装例を解説

    n分木(N-ary tree)が与えられ、その木の直径を求めることを考えます。木の直径とは、木に存在する任意の2つの葉ノードをつなぐ経路のうち、最も長いものを指します。この記事では、直径の長さを表す整数値を計算して返すプログラムをPythonで実装します。 問題の例 例えば、次のようなn分木が与えられた場合を考えてみましょう。 この場合の出力は 3 になります。 このn分木の直径は、27→14、14→42、そして42→56(または42→65)という辺から構成される経路です(図では赤線で示されています)。この経路の長さが3となるわけです。 解法のアプローチ この問題は、深さ優先探索(DFS

  2. Pythonでn分木(N-ary Tree)のルートノードを見つけるプログラム

    n分木(N-ary Tree)の各ノードが配列として与えられているとします。ここで求めたいのは、木を再構築したうえでルートノードを見つけて返すことです。返されたノードを起点に、木全体を先行順(Preorder)で表示できれば成功です。 たとえば、入力が次のような場合を考えてみましょう。 このときの出力は以下のようになります。 [14, 27, 32, 42, 56, 65] この出力は、見つけたルートノードから木の先行順走査(Preorder Traversal)を行った結果です。つまり、正しいルートさえ特定できれば、そこから木全体の構造を復元できます。 解決のアプローチ:入次数(In-d