二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
- 若左子树!=null,则左子树上所有节点的值均 < 根节点的值
- 若右子树!=null,则右子树上所有节点的值均 > 根节点的值
最优情况下,二叉搜索树为完全二叉树,其平均比较次数为: l o g 2 N log_2 N log2N
最差情况下,二叉搜索树退化为单支树,其平均比较次数为: N 2 \frac{N}{2} 2N
树的节点
ublic class Node {
public int key; // 保存的 关键字
public Node left;
public Node right;
public Node(int key) {
this.key = key;
}
}
查找:
// O(树的高度)
public boolean find(int key) {
Node current = root;
while (current != null) {
if (key == current.key) {
return true;
} else if (key < current.key) {
current = current.left;
} else {
current = current.right;
}
}
return false;
}
插入:
public void insert(int key) {
if (root == null) {
root = new Node(key);
return;
}
Node parent = null;
Node current = root;
while (current != null) {
if (key == current.key) {
throw new RuntimeException("key 重复了: " + key);
} else if (key < current.key) {
parent = current;
current = current.left;
} else {
parent = current;
current = current.right;
}
}
// current 就是 key 要插入的位置
Node node = new Node(key);
if (key < parent.key) {
parent.left = node;
} else {
parent.right = node;
}
}
删除:
8种情况参考图例:
public boolean remove(int key) {
Node parent = null;
Node current = root;
while (current != null) {
if (key == current.key) {
removeNode(parent, current);
return true;
} else if (key < current.key) {
parent = current;
current = current.left;
} else {
parent = current;
current = current.right;
}
}
return false;
}
private void removeNode(Node parent, Node current) {
if (current.left == null) {
if (current == root) {
root = current.right;
} else if (current == parent.left) {
parent.left = current.right;
} else {
parent.right = current.right;
}
} else if (current.right == null) {
if (current == root) {
root = current.left;
} else if (current == parent.left) {
parent.left = current.left;
} else {
parent.right = current.left;
}
} else {
Node nextParent = current;
Node next = current.right;
while (next.left != null) {
nextParent = next;
next = next.left;
}
current.key = next.key;
if (nextParent == current) {
nextParent.right = next.right;
} else {
nextParent.left = next.right;
}
}
}