C++ 高阶数据结构:二叉搜索树(BST)
1 二叉搜索树的概念
二叉搜索树,英文名称叫做 Binary Search Tree,简称为 BST。其是二叉树的一种,其要么是一棵空树,要么是一棵具有下列性质的二叉树:
1)若根节点的左子树不为空,那么左子树所有节点的值都小于或者等于根节点的值
2)若根节点的右子树不为空,那么右子树所有节点的值都大于或者等于根节点的值
3)根节点的左右子树又是一棵二叉搜索树
比如下面的两棵树就是二叉搜索树:

而下面这棵树就不是一棵二叉搜索树:

而且根据二叉搜索树的性质,左子树节点的值 <= 根节点的值 <= 右子树节点的值,所以如果对一棵 BST 进行中序遍历,那么遍历后的序列就是一个升序排列的序列。
2 二叉搜索树的性能
为什么会存在二叉搜索树这么一个数据结构呢?最主要的原因就是因为这个数据结构能够加快搜索的速度。因为根据二叉搜索树的性质,左子树节点的值 <= 根节点的值,右子树节点的值 >= 根节点的值,所以当我们查找一个值 x 时,只需要判断该值与根节点的关系,如果 root > x,那么就往左子树走;如果 root < x,那就往右子树走,查找次数就是二叉搜索树的高度。
一棵二叉搜索树具备以下性能:
1)在插入节点的最优情况下,二叉搜索树是一棵完全二叉树或者近似是一棵完全二叉树,其高度为 logN
2)在插入节点的最坏情况下,比如插入值的先后顺序为 [9, 8, 7, 6, 5, 4, 3, 2, 1],该搜索二叉树就会退化为一棵单叉树,树的高度就是 N(如下面的图所示)
3)综合而言,二叉搜索树的增删查改的时间复杂度平均为 O(logN),最坏情况为 O(N)

所以对于一棵普通的二叉搜索树来说,其查找的效率并不能满足我们的要求,后续将介绍两种特殊的二叉搜索树,分别是平衡二叉树(AVLTree)与红黑树(RBTree),这两种树效率都是 O(logN) 级别,会比 BST 效率更高。
值得一提的是,二分查找算法的时间复杂度也是 O(logN),但是二分查找算法的限制条件限制了其应用场景:
- 值需要存储在支持随机访问的数据结构中,一般为数组或者顺序表
- 插入和删除效率很低,因为需要大量移动元素
相比之下,AVLTree 与 RBTree 就自由很多,没有太多限制,所以 AVLTree 与 RBTree 是比二分查找算法更适合查找场景的两种数据结构。
3 二叉搜索树的增删查改(不同值的 BST)
基于之前的二叉树,二叉搜索树采取的依然是链式结构。所以在讲解二叉搜索树的增删查改之前,我们需要先创建其结构。
1)二叉搜索树的结构
(1)二叉搜索树的节点
对于二叉搜索树来说,我们并不需要知道每一个节点的父亲是谁,所以我们这里依然采用之前二叉树中的节点,也就是一个数据,两个指针,一个指向左孩子,一个指向右孩子,这里我们需要设计成模板的形式,以实现泛型编程:









