バイナリ検索ツリーの最初に、定義
バイナリツリーは、各ノードには、以上の2人の息子を持つことはできません。特別なバイナリ検索ツリーは二分木であり、Xのツリー内の各ノードは、その左の部分木のすべての項目の値は、Xのエントリ未満であり、その右側のサブツリーは、Xの全ての値よりも大きいですアイテム。
バイナリ検索ツリーノードの定義:
private static class BinaryNode<T> {
T element; // 节点的值
BinaryNode<T> left; // 左子节点
BinaryNode<T> right; // 右子节点
public BinaryNode(T element) {
this(element, null, null);
}
public BinaryNode(T element, BinaryNode<T> left, BinaryNode<T> right) {
this.element = element;
this.left = left;
this.right = right;
}
}
第二に、ツリートラバーサル
ツリートラバーサルの三種類:前順走査、順トラバーサルで、後順トラバーサル。後にここで前に、の面でルートノードからの相対です。
- 先行順走査:ルート - >左のサブツリー - >右部分木
- 予約限定:左のサブツリー - >ルート - >右部分木
- 後順:左のサブツリー - >右部分木 - >ルート
次のように以下のように木のために、異なるトラバーサルの結果は以下の通りでした。
先行順走査:ABDGHCEIF
private void preOrder(BinaryNode<T> root) {
if (root == null) {
return;
}
System.out.printf("%d ", root.element);
preOrder(root.left);
preOrder(root.right);
}
予約限定:GDHBAEICF
private void inOrder(BinaryNode<T> root) {
if (root == null) {
return;
}
inOrder(root.left);
System.out.printf("%d ", root.element);
inOrder(root.right);
}
後順:GHDBIEFCA
private void postOrder(BinaryNode<T> root) {
if (root == null) {
return;
}
postOrder(root.left);
postOrder(root.right);
System.out.printf("%d ", root.element);
}
基本操作第三に、バイナリ検索ツリー
3.1は、メソッドが含まれています
/**
* 判断树t中是否存在含有项x的节点
*
* @param x 值
* @param t 以t为根节点的一棵树
* @return
*/
private boolean contains(T x, BinaryNode<T> t) {
if (t == null) {
return false;
}
int compareResult = x.compareTo(t.element);
if (compareResult < 0) {
return contains(x, t.left);
} else if (compareResult > 0) {
return contains(x, t.right);
} else {
return true;
}
}
public boolean contains(T x) {
return contains(x, root);
}
3.2 findメソッド
/**
* 查找树t中值为x的节点
* @param x
* @param t
* @return
*/
private BinaryNode<T> find(T x, BinaryNode<T> t) {
if (t == null) {
return t;
}
int compareResult = x.compareTo(t.element);
if (compareResult < 0) {
return find(x, t.left);
} else if (compareResult > 0) {
return find(x, t.right);
} else {
return t;
}
}
public BinaryNode<T> find(T x) {
return find(x, root);
}
3.3最大値と最小値
ツリー内のノードの最大値を探します
private BinaryNode<T> findMax(BinaryNode<T> t) {
if (t == null) {
return null;
}
while (t.right != null) {
t = t.right;
}
return t;
}
public BinaryNode<T> findMax() {
return findMax(root);
}
ツリー内のノードの最小を探します
private BinaryNode<T> findMin(BinaryNode<T> t) {
if (t == null) {
return null;
}
while (t.left != null) {
t = t.left;
}
return t;
}
public BinaryNode<T> findMin() {
return findMin(root);
}
3.4 insertメソッド
private BinaryNode<T> insert(T x, BinaryNode<T> t) {
if (t == null) {
return new BinaryNode<>(x, null, null);
}
int compareResult = x.compareTo(t.element);
if (compareResult < 0) {
t.left = insert(x, t.left);
} else if (compareResult > 0) {
t.right = insert(x, t.right);
} else {
// 出现重复值,忽略不处理
}
return t;
}
public void insert(T x) {
root = insert(x, root);
}
3.5メソッドを削除します
- ノードを削除する必要がある場合は、リーフノードであり、それは直接削除することができます。
- ノードが息子を持っている場合は、そのノードにノードを置き換えるために彼の息子ましょう。
- ノードは、通常、その右のサブツリーに最小限のデータとノードデータの代わりに、二人の息子を持っているし、再帰的にそのノードを削除した場合。
public void remove(T x) {
root = remove(x, root);
}
private BinaryNode<T> remove(T x, BinaryNode<T> t) {
if (t == null) {
return t;
}
int compareResult = x.compareTo(t.element);
if (compareResult < 0) {
t.left = remove(x, t.left);
} else if (compareResult > 0) {
t.right = remove(x, t.right);
} else if (t.left != null && t.right != null) {
t.element = findMin(t.right).element;
t.right = remove(t.element, t.right);
} else {
t = (t.left != null) ? t.left : t.right;
}
return t;
}