二分探索ツリー走査には、深さ優先走査とレベル順走査の 2 種類があります。
深さ優先トラバーサルには、それぞれ、preorder ツリー ウォーク、inorder ツリー ウォーク、postorder ツリー ウォークの 3 つのタイプがあります。
- 1. 事前順序トラバーサル:最初に現在のノードにアクセスし、次に左と右のサブツリーを順番に再帰的にアクセスします。
- 2. 順序トラバーサル: 最初に左のサブツリーを再帰的に訪問し、次にそれ自体を訪問し、次に右のサブツリーを再帰的に訪問します。
- 3. ポストオーダートラバーサル: 最初に左と右のサブツリーを再帰的に訪問し、次にそれ自体のノードを訪問します。
事前注文トラバーサル結果の図:
対応するコード例:
...
// ノードをルートとする二分探索木の事前順序走査、再帰アルゴリズム
private void preOrder(Node node){ if( node != null ){ System.out.println(node.key); preOrder (node. left ); preOrder(node.right); } } ...
順序通りの走査結果の図:
対応するコード例:
...
// ノードをルートとする二分探索木の順序トラバーサル、再帰アルゴリズム
private void inOrder(Node node){ if( node != null ){ inOrder(node.left); System.out.println (node. key ); inOrder(node.right); } } ...
事後トラバーサル結果の図:
対応するコード例:
...
// ノードをルートとする二分探索木の事後探索、再帰アルゴリズム
private void postOrder(Node node){ if( node != null ){ postOrder(node.left); postOrder(node.right ); System.out.println(node.key); } } ...
Javaのサンプルコード
src/runoob/binary/Traverse.java ファイル コード:
package runoob.binary;
/**
* 優先度トラバーサル
*/
public class Traverse<Key extends Comparable<Key>, Value> { // ツリー内のノードはプライベート クラスであり、外部の世界は特定の実装を知る必要はありません二分探索ツリー ノードの プライベート クラス Node { private Key キー; private Value 値; private Node left, right; public Node(Key key, Value value) { this.key = key; this.value = value; left = right = null ; } } private Node root ; // ルート ノード private int count; // ツリー内のノードの数 type // コンストラクター、デフォルトで空の二分探索ツリーを構築 public Traverse() { root = null;
count = 0;
}
// 二分探索木内のノードの数を返す
public int size() { return count; } // 二分探索木が空かどうかを返す public boolean isEmpty() { return count == 0; } // 新しい (キー, 値) データ ペアを二分探索ツリーに挿入します public void insert(Key key, Value value){ root = insert(root, key, value); } // キー key が存在するかどうかを確認します二分探索木 public boolean contains(Key key){ return contains(root, key); } // 二分探索木でキー key に対応する値を検索します。値が存在しない場合は、null を返します public Value search(Key key){ return search( root , key ); }
// 二分探索木の事前順序走査
public void preOrder(){ preOrder(root); } // 二分探索木の順序内走査 public void inOrder(){ inOrder(root); } // 二分探索木の事後走査 public void postOrder(){ postOrder(root); } //********************** //* 二分探索木の補助関数 //**** * **************** // ノード (キー、値) をノードをルートとする二分探索ツリーに挿入し、再帰アルゴリズムを使用します。 // を挿入した後に二分探索を返します。新しいノード ツリーのルート プライベート ノード insert(ノード ノード, キー key, 値 value){ if( node == null ){ count ++; return new Node(key, value); }
if( key.compareTo(node.key) == 0 )
ノード.値 = 値;
else if( key.compareTo(node.key) < 0 )
ノード.左 = 挿入( ノード.左 , キー, 値);
else // key > node->key
node.right = insert(node.right, key, value);
return node;
} // 再帰アルゴリズム private
を使用して、node をルートとする二分探索木にキーが key のノードが含まれているかどうかを確認します。
boolean contains(ノード ノード, キー キー){ if( ノード == null ) return false; if( key.compareTo(node.key) == 0 ) return true; else if( key.compareTo(node.key) < 0 ) return contains(node.left,key);
else // key > node->key
return contains(node.right , key );
}
// ノードをルートとする二分探索木でキーに対応する値を見つける、再帰的アルゴリズム
// 値が存在しない場合は return NULL
private Value search(ノード ノード, キー key){ if( ノード == null ) return null; if( key.compareTo(node.key) == 0 ) return node.value; else if( key.compareTo(node. key) < 0 ) return search(node.left , key ); else // key > node->key return search(node.right, key ); } // ノードをルートとする二分探索ツリーを事前順序付けする トラバーサル、再帰アルゴリズム private void preOrder(Node ノード){ if( ノード != null ){
System.out.println(node.key);
preOrder(node.left);
preOrder(node.right);
}
}
// ノードをルートとする二分探索木のインオーダートラバーサル、再帰アルゴリズム
private void inOrder( Node node){ if(node != null ){ inOrder(node.left); System.out.println(node.key); inOrder(node.right); } } // ノードをルートとする二分探索 ツリーは事後探索を実行します。再帰アルゴリズム private void postOrder(Node node){ if( node != null ){ postOrder(node.left); postOrder(node.right); System.out.println(node.key); }
}
}