二叉搜索树
binary search tree , BST 常用于快速查找,插入,删除数据
对于任意一个借点满足:
- 左子树的所有节点小于右子树
- 右子树的所有节点大于左子树
- 左右子树也是bst(递归)
8
/ \
3 10
/ \ \
1 6 14
/ \ /
4 7 13
🔍 基本操作
1. 查找(Search)
从根开始:
- 如果目标值 == 当前节点 → 找到
- 如果目标值 < 当前节点 → 去左子树
- 如果目标值 > 当前节点 → 去右子树
时间复杂度:
- 平均:O(log n)
- 最坏(退化成链表):O(n)
2. 插入(Insert)
步骤:
- 从根开始比较
- 小 → 左走,大 → 右走
- 找到空位置插入
3. 删除(Delete)
删除比较复杂,有三种情况:
✔ 情况1:叶子节点
直接删除
原: 3
/
1
删后: 3
✔ 情况2:只有一个子节点
用子节点替代父节点 删除子节点
原: 3
\
6
删后: 6
✔ 情况3:有两个子节点
8
/ \
3 10
/
9
用9替换8 删除9
常用方法:
- 找 右子树最小值(或左子树最大值)
- 替换当前节点
- 再删除那个替代节点
刚好比当前节点大(合法放右边)又不会比右子树其他节点大(不会乱)
🔁 遍历方式
1. 中序遍历(最重要)
左 → 根 → 右
👉 得到 有序序列(从小到大)
2. 其他遍历
- 前序:根 → 左 → 右
- 后序:左 → 右 → 根
- 层序:一层一层遍历
⚠️问题:退化
如果插入顺序是:
1, 2, 3, 4, 5
树会变成:
1
\
2
\
3
\
4
\
5
👉 变成链表,效率变差
改进结构
- AVL 树(严格平衡)
- 红黑树(工程常用,如 Java TreeMap)
- B 树 / B+ 树(数据库用)
code
package com.jasper.bst;
import lombok.Data;
/**
* @author jasper
* @since 2026-04-24 22:09:11
*/
@Data
public class Treenode {
int val;
Treenode left, right;
public Treenode(int val) {
this.val = val;
}
}
package com.jasper.bst;
/**
* @author jasper
* @since 2026-04-23 17:41:01
*/
public class BST {
public Treenode insert(Treenode root, int val) {
if (root == null) return new Treenode(val);
Treenode current = root;
while (true) {
if (val < current.val) {
if (current.left == null) {
current.left = new Treenode(val);
break;
}
// 一直往下走
current = current.left;
} else {
if (current.right == null) {
current.right = new Treenode(val);
break;
}
current = current.right;
}
}
return root;
}
public Treenode delete(Treenode root, int key) {
if (root == null) {
return null;
}
if (key < root.val) {
root.left = delete(root.left, key);
} else if (key > root.val) {
root.right = delete(root.right, key);
} else {
// 找到要删除的节点
// 返回的是新子树根 叶子节点 || 单子节点
if (root.left == null) return root.right;
if (root.right == null) return root.left;
// 俩个子节点 找右子树最小
Treenode success = root.right;
while (success.left != null) success = success.left;
// root和右子树最小节点替换
root.val = success.val;
// 删除替换节点
root.right = delete(root.right, success.val);
}
return root;
}
}