/**
* 二叉查找树
*
* @param <Key>
* @param <Value>
*/
public class BinaryTree<Key extends Comparable<Key>, Value> {
/********************************************
* 二叉查找树,实现核心功能
* 1.插入
* 2.查找
* 3.删除
* 4.查询最小值
* 5.查询最大值
********************************************/
// 记录根节点
private Node root;
// 记录树中元素的个数
private int N;
/**
* 树节点结构体类
*/
private class Node {
public Key key; // 存储键
public Value value; // 存储值
public Node left; // 记录左子节点
public Node right; // 记录右子节点
public Node(Key key, Value value, Node left, Node right) {
this.key = key;
this.value = value;
this.left = left;
this.right = right;
}
}
// 获取树中元素的个数
public int getSize() {
return N;
}
// 向树中添加元素 key-value
public void put(Key key, Value value) {
root = put(root, key, value);
}
// 向指定的树x中添加key-value,并返回添加元素后的新树
private Node put(Node x, Key key, Value value) {
// 如果x的子树为空
if (x == null) {
N++;
return new Node(key, value, null, null);
}
// 如果x的子树不为空,则比较x节点的键和key的大小
// 如果key小于x结点的键,则继续找x结点的左子树。如果key大于x结点的键,则继续找x结点的右子树,如果key等于x结点的键,则替换x结点的值为value即可。
int cmp = key.compareTo(x.key);
if (cmp > 0) {
x.right = put(x.right, key, value);
} else if (cmp < 0) {
x.left = put(x.left, key, value);
} else {
x.value = value;
}
return x;
}
// 查询树中指定的key对应的value
public Value get(Key key) {
return get(root, key);
}
// 从指定的树x中,查找key对应的值
private Value get(Node x, Key key) {
// x树为NULL
if (x == null) {
return null;
}
// x树不为NULL,比较键的大小
// 如果key小于x结点的键,则继续找x结点的左子树。如果key大于x结点的键,则继续找x结点的右子树,如果key等于x结点的键,则返回该键的值
int cmp = key.compareTo(x.key);
if (cmp > 0) {
return get(x.right, key);
} else if (cmp < 0) {
return get(x.left, key);
} else {
return x.value;
}
}
// 删除树中key对应的value
public void delete(Key key) {
delete(root, key);
}
// 删除指定树x中key对应的value,并返回删除后的新树
private Node delete(Node x, Key key) {
// x树为null
if (x == null) {
return null;
}
// x树不为NULL,比较键的大小
// 如果key小于x结点的键,则继续找x结点的左子树。如果key大于x结点的键,则继续找x结点的右子树,如果key等于x结点的键,执行真正的删除操作
int cmp = key.compareTo(x.key);
if (cmp > 0) {
return x.right = delete(x.right, key);
} else if (cmp < 0) {
return x.left = delete(x.left, key);
} else {
N--;
if (x.right == null) {
return x.left;
}
if (x.left == null) {
return x.right;
}
// 找到右子树的最小结点
Node minNode = x.right;
while (minNode.left != null) {
minNode = minNode.left;
}
// 删除右子树中最小的结点
Node n = x.right;
while (n.left != null) {
if (n.left.left == null) {
n.left = null;
} else {
n = n.left; // 变换n结点
}
}
// 让x结点的左子树成为minNode的左子树
minNode.left = x.left;
// 让x结点的右子树成为minNode的右子树
minNode.right = x.right;
// 让x结点的父结点指向minNode
x = minNode;
return x;
}
}
// 找出整个树中最小的键
public Key getMin() {
return min(root).key;
}
// 找到指定树x中最小值的键所在的结点
private Node min(Node x) {
if (x.left != null) {
return min(x.left);
} else {
return x;
}
}
// 找出整个树中最大的键
public Key getMax() {
return max(root).key;
}
// 找到指定树x中最大值的键所在的结点
private Node max(Node x) {
if (x.right != null) {
return max(x.right);
} else {
return x;
}
}
}