自己實現一個二叉查詢樹BinarySearchTree
阿新 • • 發佈:2019-01-02
需求
自己實現一個簡單的二叉查詢樹BinarySearchTree
二叉排序樹或者是一棵空樹,或者是具有下列性質的二叉樹:
- 若左子樹不空,則左子樹上所有結點的值均小於或等於它的根結點的值;
- 若右子樹不空,則右子樹上所有結點的值均大於或等於它的根結點的值;
- 左、右子樹也分別為二叉排序樹;
圖示
包含功能:
- insert
- remove
- contains
- findMax
- findMin
- toString
程式碼:
import java.util.NoSuchElementException;
import java.util.StringJoiner;
public class BinarySearchTree<T extends Comparable<? super T>> {
private BinaryNode<T> root;
public BinarySearchTree() {
root = null;
}
public BinarySearchTree(T[] arr) {
for (T t : arr) {
insert(t);
}
}
public void markEmpty () {
root = null;
}
public boolean isEmpty() {
return root == null;
}
public boolean contains(T t) {
return contains(t, root);
}
public T findMin() {
if (isEmpty())
throw new NoSuchElementException();
return findMin(root).element;
}
public T findMax() {
if (isEmpty())
throw new NoSuchElementException();
return findMax(root).element;
}
public void insert(T t) {
root = insert(t, root);
}
public void remove(T t) {
root = remove(t, root);
}
@Override
public String toString() {
StringJoiner joiner = new StringJoiner(" ", "[", "]");
listAll(this.root, joiner);
return joiner.toString();
}
private void listAll(BinaryNode<T> node, StringJoiner joiner) {
if (node.left != null)
listAll(node.left, joiner);
joiner.add(node.element.toString());
if (node.right != null)
listAll(node.right, joiner);
}
private boolean contains(T t, BinaryNode<T> node) {
if (node == null)
return false;
int compareResult = t.compareTo(node.element);
if (compareResult < 0)
return contains(t, node.left);
else if (compareResult > 0)
return contains(t, node.right);
else
return true;
}
private BinaryNode<T> findMin(BinaryNode<T> node) {
if (node == null)
return null;
if (node.left == null)
return node;
return findMin(node.left);
}
private BinaryNode<T> findMax(BinaryNode<T> node) {
if (node == null)
return null;
while (node.right != null)
node = node.right;
return node;
}
private BinaryNode<T> insert(T t, BinaryNode<T> node) {
if (node == null)
return new BinaryNode<T>(t);
int compareResult = t.compareTo(node.element);
if (compareResult < 0)
node.left = insert(t, node.left);
else if (compareResult > 0)
node.right = insert(t, node.right);
return node;
}
private BinaryNode<T> remove(T t, BinaryNode<T> node) {
if (node == null)
return null;
int compareResult = t.compareTo(node.element);
if (compareResult < 0) {
node.left = remove(t, node.left);
} else if (compareResult > 0) {
node.right = remove(t, node.right);
} else if (node.left != null && node.right != null) {
// two children
node.element = findMin(node.right).element;
node.right = remove(node.element, node.right);
} else {
node = (node.left != null) ? node.left : node.right;
}
return node;
}
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;
}
}
}