C++ 二叉搜索树详解:原理、操作与 Key/Value 场景
参考文档
- 非官方文档:cplusplus
- 官方文档:cppreference
前言
从二叉搜索树到 map 和 set 的使用,再到 AVL 树、红黑树的实现,这是一个整体。在接触平衡搜索二叉树之前,我们需要先掌握基础的数据结构——二叉搜索树(Binary Search Tree, BST)。理解其底层逻辑,有助于后续更好地掌握 STL 容器。
1. 理解二叉搜索树
1.1 概念
二叉搜索树又称二叉排序树。它或者是一棵空树,或者是具有以下性质的二叉树:
- 若它的左子树不为空,则左子树上所有结点的值都小于等于根结点的值;
- 若它的右子树不为空,则右子树上所有结点的值都大于等于根结点的值;
- 它的左右子树也分别为二叉搜索树。
注意:二叉搜索树中可以支持插入相等的值,也可以不支持。具体取决于使用场景定义。例如
std::map/std::set不支持插入相等值,而multimap/multiset支持。
1.2 核心特性
- 灵活的数据结构:BST 支持动态数据集合的高效操作,适合频繁插入、删除和查找的场景。
- 天然的搜索优势:利用二叉树的分支特性,BST 在平均情况下能实现 O(log n) 的搜索效率。
2. 性能分析
2.1 时间复杂度
- 最优情况:树为完全二叉树(或接近完全),高度约为 log N,增删查改时间复杂度为 O(log N)。
- 最差情况:树退化为单支树(类似链表),高度为 N,时间复杂度退化为 O(N)。
综合而言,普通二叉搜索树的时间复杂度为 O(N)。为了应对极端情况,后续通常会引入平衡二叉搜索树(如 AVL 树、红黑树)来保证性能。
2.2 与二分查找对比
二分查找也能实现 O(log N) 的查找效率,但存在两大缺陷:
- 需要存储在支持下标随机访问的结构中,且必须有序;
- 插入和删除数据效率低,因为涉及大量数据移动。
相比之下,BST 在内存中存储更灵活,插入删除无需移动数据,但需警惕退化为单支树的情况。
3. 实现二叉搜索树的定义
3.1 命名规范
通常简写为 BST。节点类命名为 BSTreeNode,树类命名为 BSTree。
3.2 节点定义
template<class K>
struct BSTreeNode {
BSTreeNode<K>* _left;
BSTreeNode<K>* _right;
K _key;
BSTreeNode(const K& key) : _left(), _right(), _key(key) {}
};


