定义
对于二叉查找树的每个节点X,它的左子树中的所有项的值都小于X项的值,而它的右子树中的所有项的值都大于X项的值
insert
递归实现
/** * 递归实现 * 由于t引用该树的根,而根又在第一次插入的时候发生变化,因此insert被写成一个对新树根引用的方法。 * * @param x * @param t */
private Node<T> insert1(T x, Node<T> t) {
if (t == null) {
return new Node<T>(x, null, null);
} else {
int compare = x.compareTo(t.data);
if (compare < 0) {
t.left = insert1(x, t.left);
} else if (compare > 0) {
t.right = insert1(x, t.right);
}
return t;
}
}
非递归实现
private void insert(T x, Node<T> t) {
if (t == null) {
root = new Node<T>(x, null, null);
} else {
Node<T> pNode = null;
while (t != null) {
if (x.compareTo(t.data) == 0) {
return;
} else if (x.compareTo(t.data) > 0) {
pNode = t;
t = t.right;
} else {
pNode = t;
t = t.left;
}
}
Node<T> newNode = new Node<>(x, null, null);
if (x.compareTo(pNode.data) < 0) {
pNode.left = newNode;
} else {
pNode.right = newNode;
}
}
}
contains方法
//递归实现
private boolean contains(T element, Node<T> t) {
if (t == null) {
return false;
}
if (element.compareTo(t.data) > 0) {
return contains(element, t.right);
} else if (element.compareTo(t.data) < 0) {
return contains(element, t.left);
} else {
return true;
}
}
//非递归实现
private boolean contains1(T element, Node<T> t) {
if (t == null) {
return false;
}
while (t != null) {
if (element.compareTo(t.data) > 0) {
t = t.right;
} else if (element.compareTo(t.data) < 0) {
t = t.left;
} else {
return true;
}
}
return false;
}
findMin方法
//这里使用尾递归实现,可以用while代替,参考findMax
private T findMin(Node<T> t) {
if (t == null) {
return null;
} else if (t.left == null) {
return t.data;
} else {
return findMin(t.left);
}
}
findMax方法
//非递归实现
private T findMax(Node<T> node) {
if (node != null) {
while (node.right != null) {
node = node.right;
}
}
return node.data;
}
remove方法
- 如果节点是一个树叶,可以直接删除
- 如果节点有一个儿子,则该节点可以在父节点调整自己的链以绕过该节点后被删除
- 如果该节点有两个儿子,先找到其右子树最小的节点替代当前节点,然后递归删除之前那个右子树最小节点
public T remove(T x) {
return (root = remove(x, root)).data;
}
/** * @param x the item to remove * @param t the node that roots the subtree * @return the new root of the subtree */
private Node<T> remove(T x, Node<T> t) {
if (t == null) {
return t;
}
int compare = x.compareTo(t.data);
if (compare < 0) {
t.left = remove(x, t.left);
} else if (compare > 0) {
t.right = remove(x, t.right);
} else if (t.left != null && t.right != null) {
t.data = findMin(t.right);
t.right = remove(t.data, t.right);
} else {
t = (t.left != null) ? t.left : t.right;
}
return t;
}
全部代码
public class BinarySearchTree<T extends Comparable<? super T>> {
public static class Node<T> {
T data;
Node<T> left;
Node<T> right;
public Node(T data, Node<T> leftChild, Node<T> rightChild) {
super();
this.data = data;
this.left = leftChild;
this.right = rightChild;
}
}
private Node<T> root;
public BinarySearchTree() {
root = null;
}
public void insert(T x) {
insert(x, root);
}
public boolean contains(T x) {
return contains(x, root);
}
/** * 尾递归实现 * * @param element * @param root * @return */
private boolean contains(T element, Node<T> t) {
if (t == null) {
return false;
}
if (element.compareTo(t.data) > 0) {
return contains(element, t.right);
} else if (element.compareTo(t.data) < 0) {
return contains(element, t.left);
} else {
return true;
}
}
public boolean contains1(T x) {
return contains1(x, root);
}
/** * 尾递归可以很容易的利用while替代 * * @param element * @param t * @return */
private boolean contains1(T element, Node<T> t) {
if (t == null) {
return false;
}
while (t != null) {
if (element.compareTo(t.data) > 0) {
t = t.right;
} else if (element.compareTo(t.data) < 0) {
t = t.left;
} else {
return true;
}
}
return false;
}
public T findMin() {
return findMin(root);
}
/** * 尾递归实现 * * @param t * @return */
private T findMin(Node<T> t) {
if (t == null) {
return null;
} else if (t.left == null) {
return t.data;
} else {
return findMin(t.left);
}
}
public T findMax() {
return findMax(root);
}
/** * 非尾递归实现 * * @param node * @return */
private T findMax(Node<T> node) {
if (node != null) {
while (node.right != null) {
node = node.right;
}
}
return node.data;
}
/** * 非递归实现 * * @param x * @param t */
private void insert(T x, Node<T> t) {
if (t == null) {
root = new Node<T>(x, null, null);
} else {
Node<T> pNode = null;
while (t != null) {
if (x.compareTo(t.data) == 0) {
return;
} else if (x.compareTo(t.data) > 0) {
pNode = t;
t = t.right;
} else {
pNode = t;
t = t.left;
}
}
Node<T> newNode = new Node<>(x, null, null);
if (x.compareTo(pNode.data) < 0) {
pNode.left = newNode;
} else {
pNode.right = newNode;
}
}
}
public void insert1(T x) {
root = insert1(x, root);
}
/** * 递归实现 * 由于t引用该树的根,而根又在第一次插入的时候发生变化,因此insert被写成一个对新树根引用的方法。 * * @param x * @param t */
private Node<T> insert1(T x, Node<T> t) {
if (t == null) {
return new Node<T>(x, null, null);
} else {
int compare = x.compareTo(t.data);
if (compare < 0) {
t.left = insert1(x, t.left);
} else if (compare > 0) {
t.right = insert1(x, t.right);
}
return t;
}
}
public void midOrder() {
midOrder(root);
}
private void midOrder(Node<T> root) {
if (root == null) {
return;
}
midOrder(root.left);
System.out.println(root.data);
midOrder(root.right);
}
public T remove(T x) {
return (root = remove(x, root)).data;
}
/** * @param x the item to remove * @param t the node that roots the subtree * @return the new root of the subtree */
private Node<T> remove(T x, Node<T> t) {
if (t == null) {
return t;
}
int compare = x.compareTo(t.data);
if (compare < 0) {
t.left = remove(x, t.left);
} else if (compare > 0) {
t.right = remove(x, t.right);
} else if (t.left != null && t.right != null) {
t.data = findMin(t.right);
t.right = remove(t.data, t.right);
} else {
t = (t.left != null) ? t.left : t.right;
}
return t;
}
public static void main(String[] args) {
BinarySearchTree<Integer> tree = new BinarySearchTree<>();
int[] array = {6, 2, 8, 1, 5, 3, 4};
for (int i : array) {
tree.insert1(i);
}
tree.midOrder();
System.out.println("contains(8) " + tree.contains1(8));
System.out.println("contains(7) " + tree.contains1(7));
System.out.println("findMin() " + tree.findMin());
System.out.println("findMax() " + tree.findMax());
System.out.println("remove() " + tree.remove(5));
tree.midOrder();
}
}