二分探索木は何ですか
バイナリ二分探索木のいずれかの空の木である(二分探索木)、または以下の特性を有する:その左サブツリーが空でない場合、次に、全てのノードが以下のルートより左の部分木の値であります値ノードと、その右側のサブツリーが空でない場合、右の部分木の値は、すべてのノードがルートの値よりも大きい、その左右のサブツリーは二分探索木です。各サブツリーノードは、特性を満たすように形成されています。
定義ツリーノード
public class BST01<E extends Comparable<E>> {
private class Node {
E e;
Node left; //左子节点
Node right; //右子节点
public Node(E e) {
this.e = e;
}
}
}
ノードの追加
ルートノードの属性を定義します。 Node root;
リカーシブ
public void add(E e) {
root = add(root, e);
}
private Node add(Node node, E e) {
if (node == null) {
return new Node(e);
}
if (e.compareTo(node.e) > 0) {
node.right = add(node.right, e);
} else /*if (e.compareTo(node.e) < 0)*/ {
node.left = add(node.left, e);
}
return node;
}
注釈が開かれている場合、自由=ノードと、上記を達成するためにそうでなければ、それが<=ノードが含まれています。
達成するためのサイクル
public void addByCircle(E e) {
if (root == null) {
root = new Node(e);
} else {
Node p = root;
while (p != null) {
if (e.compareTo(p.e) > 0) {
if (p.right == null) {
p.right = new Node(e);
break;
} else {
p = p.right;
}
} else /*if (e.compareTo(p.e) < 0)*/ {
if (p.left == null) {
p.left = new Node(e);
break;
} else {
p = p.left;
}
} /*else {
break;
}*/
}
}
}
上記を達成するためにそうでなければ、それが<=ノードを含む; 2つの注釈が開いた場合、自由=ノード。
階層トラバーサル(幅優先トラバーサル)
ツリーノードE内のすべての要素の値を出力し、階層順に印刷されます。
public void levelOrder1() {
Queue<Node> queue = new LinkedList<>();
queue.add(root);
StringBuilder sb = new StringBuilder();
while (!queue.isEmpty()) {
Node node = queue.remove();
sb.append(node.e + " ");
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
System.out.println(sb);
}
各ノードは削除、ルートから開始し、それはFIFOキューに左と右の子ノードを維持します。
テスト
public static void main(String[] args) {
BST01<Integer> bst = new BST01<>();
bst.add(33);
bst.add(31);
bst.add(36);
bst.add(19);
bst.add(92);
bst.add(9);
bst.add(38);
bst.add(98);
bst.add(43);
bst.add(54);
bst.add(54);
bst.add(98);
bst.add(19);
bst.levelOrder1();
}
輸出
33 31 36 19 92 9 38 98 19 43 98 54 54
深さ属性ノードのレベルの増加
上記の出力から、ビュー階層は、非常に明確ではありません。
次に、Node
深度表現性のレベルを追加depth
private class Node {
E e;
Node left;
Node right;
int depth;
public Node(E e) {
this.e = e;
}
public Node(E e, int depth) {
this(e);
this.depth = depth;
}
}
したがって、ノードのトラバーサル方法を変更し、追加します。
最終的には、以下の
public class BST01<E extends Comparable<E>> {
private class Node {
E e;
Node left;
Node right;
int depth;
public Node(E e) {
this.e = e;
}
public Node(E e, int depth) {
this(e);
this.depth = depth;
}
}
private Node root;
public void add(E e) {
root = add(root, e, 0);
}
private Node add(Node node, E e, int depth) {
if (node == null) {
return new Node(e, depth);
}
if (e.compareTo(node.e) > 0) {
node.right = add(node.right, e, depth + 1);
} else /*if (e.compareTo(node.e) <= 0)*/ {
node.left = add(node.left, e, depth + 1);
}
return node;
}
public void addByCircle(E e) {
if (root == null) {
root = new Node(e);
root.depth = 0;
} else {
Node p = root;
while (p != null) {
if (e.compareTo(p.e) > 0) {
if (p.right == null) {
p.right = new Node(e, p.depth + 1);
break;
} else {
p = p.right;
}
} else /*if (e.compareTo(p.e) < 0)*/ {
if (p.left == null) {
p.left = new Node(e, p.depth + 1);
break;
} else {
p = p.left;
}
} /*else {
break;
}*/
}
}
}
public void levelOrder1() {
Queue<Node> queue = new LinkedList<>();
queue.add(root);
StringBuilder sb = new StringBuilder();
while (!queue.isEmpty()) {
Node node = queue.remove();
sb.append(node.e + " ");
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
System.out.println(sb);
}
public void levelOrder2() {
Queue<Node> queue = new LinkedList<>();
queue.add(root);
StringBuilder sb = new StringBuilder();
int tempDepth = -1;
while (!queue.isEmpty()) {
Node node = queue.remove();
if (tempDepth != node.depth) {
sb.append("\n");
}
sb.append(node.e + "(depth=" + node.depth +") ");
tempDepth = node.depth;
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
System.out.println(sb);
}
}
テスト
同じテストデータを追加し、呼び出しlevelOrder2()
トラバーサルを。
輸出
33(depth=0)
31(depth=1) 36(depth=1)
19(depth=2) 92(depth=2)
9(depth=3) 38(depth=3) 98(depth=3)
19(depth=4) 43(depth=4) 98(depth=4)
54(depth=5)
54(depth=6)
この出力構造は、この二分探索木がより直感的に理解します。
ツリー全体は次のようになります。
33
31 36
19 92
9 38 98
19 43 98
54
54