什么是二叉搜索树
二叉搜索树(Binary Search Tree, BST)又称二叉排序树。它或者是一棵空树,或者是具有以下性质的二叉树:
- 左子树上所有节点的值都小于等于根结点的值;
- 右子树上所有节点的值都大于等于根结点的值;
- 它的左右子树也分别为二叉搜索树。
注意:二叉搜索树中可以支持插入相等的值,也可以不支持。具体取决于使用场景定义。例如标准库中的 std::map/std::set 不支持插入相等值,而 std::multimap/std::multiset 支持。
性能分析
在最优情况下,二叉搜索树为完全二叉树(或接近完全二叉树),其高度约为 log₂N。
最差情况下,二叉搜索树退化为单支树(类似链表),其高度为 N。
因此平均时间复杂度为 O(log n),最差情况为 O(n)。
虽然二分查找也能实现 O(log₂N) 级别的查找效率,但存在两大缺陷:
- 需要存储在支持下标随机访问的结构中,并且数据必须有序。
- 插入和删除数据效率很低,因为存储在下标随机访问的结构中,插入和删除通常需要挪动大量数据。
Key 类型二叉搜索树的实现
后续要学习的 std::set/std::multiset 容器底层数据结构就是红黑树——一种'近似平衡'的二叉搜索树。对于 set/multiset 容器,集合是一种按照特定顺序存储唯一元素的容器。
节点结构
template<class K> struct BSTNode {
K _key;
BSTNode<K>* _left;
BSTNode<K>* _right;
BSTNode(const K& key = 0)
:_key(key), _left(nullptr), _right(nullptr) {}
};
类结构
template<class K> class BSTree {
using Node = BSTNode<K>;
public:
// ... 成员函数
private:
Node* _root = nullptr;
};
下面实现过程中默认为值不重复的情形。
插入操作
思路如下:
- 若树为空,直接新增结点,赋值给 root 指针。
- 若树不空,按二叉搜索树性质,用 cur 指针遍历,parent 指针记下父亲节点。若插入值 key 比当前节点大往右走,小则往左走,直到找到空位置插入新结点。
- 确定新节点是插在 parent 的左边还是右边。


