二分探索木の層順走査、つまり層ごとの走査、つまり各層のノードがキューに格納され、その後、デキュー(ノードを取り出す)とキュー(ノードを格納する)の操作が行われます。次の層) の目標を達成するために実行されます。
キューを導入することでレイヤー順序のトラバーサルをサポートします。
-
ルート ノードが空の場合、トラバーサルは行われません。
-
ルート ノードが空でない場合:
-
最初にルート ノードをキューに入れます。
-
キューが空でない限り:
- チームの最初のノードをデキューしてトラバースします。
- チームのヘッド ノードに左の子がある場合は、左の子をチームに追加します。
- チームのヘッド ノードに適切な子がある場合は、その適切な子をチームに追加します。
-
次の手順を順番に説明します。
(1)まずルートノードを取り出してキューに入れます
(2) 29を取り出し、左右の子ノードがチームに加わる
(3)チームヘッド 17 がチームを離れ、子ノード 14 と 23 がチームに参加します。
(4) 31 がデキューされ、子ノード 30 と 43 がエンキューされます。
(5)ついに全員がチームから脱退
コアコードの例:
...
// 二分探索ツリーのレベル順の走査
public void levelOrder(){ // LinkedList をキューとして使用します LinkedList<Node> q = new LinkedList<Node>(); q.add(root); while ( ! q.isEmpty() ){ ノードnode = q.remove(); System.out.println(node.key); if(node.left != null ) q.add(node.left); if(node.right != null ) q.add(node.right ); } } ...
Javaのサンプルコード
src/runoob/binary/LevelTraverse.java ファイルコード:
package runoob.binary;
import java.util.LinkedList;
/**
* レベル順序トラバーサル
*/
public class LevelTraverse<Key extends Comparable<Key>, Value>{ // ツリー内のノードはプライベート クラスであり、外部の世界はプライベート クラスです。知る必要はありません 二分探索ツリーノードの具体的な実現 private class Node { private Key key; private Value 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 LevelTraverse() {
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); } // バイナリが存在するかどうかを確認しますsearchtree is キーあり key public boolean contain(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); } // 二分探索木のレベル順序走査 public void levelOrder(){ // LinkedList をキューとして使用 LinkedList<Node> q = new LinkedList< Node> (); q.add(root); while( !q.isEmpty() ){ ノードnode = q.remove(); System.out.println(node.key); if( node.left != null )
q.add(node.left );
if(node.right != null )
q.add(node.right );
}
}
//****************** *
//* 二分探索木の補助関数
//*********************
// 再帰アルゴリズムを使用してノード (キー、値) を挿入
// ルートを返す新しいノードを挿入した後の二分探索ツリーの
プライベート ノード insert(ノード ノード, キー キー, 値 value){ if( ノード == null ){ count ++; return new Node(key , value); } if( key.比較To(node.key) == 0 ) ノード.値 = 値; else if( key.compareTo(node.key) < 0 )
node.left = insert(node.left , key, value);
else // key > node->key
node.right = insert(node.right, key, value);
return node;
}
// ノードをルートとするビュー二分探索ツリーにキー値が key であるノードが含まれている場合は、再帰アルゴリズムを使用します。 private boolean contains
(Node node, Key key){ if( node == 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 ); } / / ノードをルートとする二分探索木でキーに対応する値を見つける、再帰的アルゴリズム
// 値が存在しない場合は、NULL を返します
private Value search(Node node, Key key){ if( node == 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 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(ノード.right); System.out.println(node.key); } } }