二叉查找树的基本概念
二叉查找树(Binary Search Tree, BST)是一种特殊的二叉树,满足以下性质:
- 左子树上所有节点的值小于根节点的值
- 右子树上所有节点的值大于根节点的值
- 左右子树也分别为二叉查找树
这种结构使得查找、插入和删除操作的平均时间复杂度为O(log n),最坏情况下为O(n)。
节点定义与初始化
使用整型变量存储节点值,通过数组模拟树结构。定义三个数组:val存储节点值,l存储左子节点索引,r存储右子节点索引,初始时所有值为-1表示空节点。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000;
int val[MAXN], l[MAXN], r[MAXN];
int root = -1, cnt = 0;
插入操作
插入新节点时,从根节点开始比较,小于当前节点则向左子树查找,大于则向右子树查找,直到找到空位置。
void insert(int x) {
if (root == -1) {
root = cnt;
val[cnt] = x;
cnt++;
return;
}
int cur = root;
while (true) {
if (x < val[cur]) {
if (l[cur] == -1) {
l[cur] = cnt;
val[cnt] = x;
cnt++;
break;
}
cur = l[cur];
} else {
if (r[cur] == -1) {
r[cur] = cnt;
val[cnt] = x;
cnt++;
break;
}
cur = r[cur];
}
}
}
查找操作
查找操作与插入类似,通过比较节点值决定搜索方向,找到返回true,否则返回false。
bool search(int x) {
int cur = root;
while (cur != -1) {
if (x == val[cur]) return true;
cur = x < val[cur] ? l[cur] : r[cur];
}
return false;
}
删除操作
删除操作分为三种情况:
- 删除叶子节点:直接移除
- 删除有一个子节点的节点:用子节点替代
- 删除有两个子节点的节点:用后继节点(右子树的最小值)替代
int find_min(int node) {
while (l[node] != -1) node = l[node];
return node;
}
void delete_node(int x) {
int cur = root, par = -1;
// 查找要删除的节点及其父节点
while (cur != -1 && val[cur] != x) {
par = cur;
cur = x < val[cur] ? l[cur] : r[cur];
}
if (cur == -1) return; // 未找到
// 情况1:有两个子节点
if (l[cur] != -1 && r[cur] != -1) {
int suc = find_min(r[cur]);
int tmp = val[suc];
delete_node(tmp);
val[cur] = tmp;
return;
}
// 情况2和3:有一个或零个子节点
int child = (l[cur] != -1) ? l[cur] : r[cur];
if (par == -1) root = child; // 删除的是根节点
else if (l[par] == cur) l[par] = child;
else r[par] = child;
}
遍历操作
二叉查找树的中序遍历会产生有序序列。
void inorder(int node) {
if (node == -1) return;
inorder(l[node]);
cout << val[node] << " ";
inorder(r[node]);
}
示例与测试
以下是一个简单的测试示例:
int main() {
insert(50);
insert(30);
insert(70);
insert(20);
insert(40);
insert(60);
insert(80);
cout << "Inorder traversal: ";
inorder(root);
cout << endl;
cout << "Search 40: " << (search(40) ? "Found" : "Not found") << endl;
cout << "Search 90: " << (search(90) ? "Found" : "Not found") << endl;
delete_node(20);
cout << "After deleting 20: ";
inorder(root);
cout << endl;
delete_node(30);
cout << "After deleting 30: ";
inorder(root);
cout << endl;
delete_node(50);
cout << "After deleting 50: ";
inorder(root);
cout << endl;
return 0;
}
时间复杂度分析
- 查找、插入、删除操作的平均时间复杂度为O(log n)
- 最坏情况下(树退化为链表)时间复杂度为O(n)
- 中序遍历的时间复杂度为O(n)
平衡二叉查找树
为避免最坏情况,可以使用平衡二叉查找树(如AVL树、红黑树),通过旋转操作保持树的平衡,确保操作时间复杂度为O(log n)。
10万+





