C++ 二叉搜索树
一、二叉搜索树的性能分析和概念
1.1 二叉搜索树的概念
二叉搜索树又称二叉排序树,它或者是一棵空树,是一种具有以下性质的二叉树:
- 若它的左子树不为空,则左子树上所有结点的值都小于等于根结点的值。
- 若它的右子树不为空,则右子树上所有结点的值都大于等于根结点的值。
- 它的左右子树都是二叉搜索树。
- 二叉搜索树中可以支持插入相等的值,也可以不支持插入相等的值,具体看使用场景定义。例如:map/set/multimap/multiset 系列容器底层就是二叉搜索树,其中 map/set 不支持插入相等值,multimap/multiset 支持插入相等值。
1.2 二叉搜索树的性能分析
由于它本身和它的子树都是二叉搜索树,观察上述特点不难发现:二叉搜索树的中序遍历一定是升序序列(所以二叉搜索树又称二叉排序树)。

二叉搜索树顾名思义,其优势在于搜索效率高。下面我们来分析其最优情况和最差情况:
- 最优情况下,二叉搜索树为完全二叉树(或者接近完全二叉树),其高度为:log₂N。
- 最差情况下,二叉搜索树退化为单支树(或者类似单支),其高度为:N。
所以综合而言二叉搜索树增删查改时间复杂度为:O(N)。那么这样的效率显然是无法满足我们需求的,必须将二叉搜索树优化即二叉搜索树的变形:平衡二叉搜索树 AVL 树和红黑树,才能适用于我们在内存中存储和搜索数据。
有的人说使用二分查找也可以实现 O(log₂N) 级别的查找效率,为何还要将二叉搜索树变形?需要说明的是,二分查找也可以实现 O(log₂N) 级别的查找效率,但是二分查找有两大缺陷:
- 需要存储在支持下标随机访问的结构中,并且有序。
- 插入和删除数据效率很低,因为存储在下标随机访问的结构中,插入和删除数据一般需要挪动数据。
这里也就体现出了平衡二叉搜索树的价值。

二、二叉搜索树增删查的实现
这里不支持修改(修改一个就可能不是二叉搜索树的结构了)。
2.1 二叉搜索树基本结构的实现
2.1.1 节点的定义
由于后面实现二叉搜索树要访问节点成员,所以这里使用 struct 定义(默认是公有):
template<class K> struct BSTreeNode {
BSTreeNode* _left;
BSTreeNode* _right;
K _key;
BSTreeNode(const K& key) :_left(nullptr), _right(nullptr), _key(key) { }
};




