二叉搜索树的概念与性能
二叉搜索树(Binary Search Tree,简称 BST)又称二叉排序树。它要么是一棵空树,要么满足以下性质:
- 若左子树不为空,则左子树上所有结点的值都小于等于根结点的值。
- 若右子树不为空,则右子树上所有结点的值都大于等于根结点的值。
- 左右子树本身也是二叉搜索树。
关于相等值的处理,具体取决于使用场景。例如 std::map/std::set 不支持插入相等键,而 multimap/multiset 支持。这完全由底层容器的定义决定。
性能分析
由于中序遍历的结果一定是升序序列,BST 非常适合用于有序数据的存储和查找。
其时间复杂度高度依赖于树的高度:
- 最优情况:树接近完全二叉树,高度为 $\log_2 N$,操作复杂度为 $O(\log N)$。
- 最差情况:树退化为单支树(类似链表),高度为 $N$,操作复杂度降为 $O(N)$。
这种不稳定性意味着在极端情况下效率无法满足需求,因此衍生出了平衡二叉搜索树(如 AVL 树、红黑树)。虽然二分查找也能达到 $O(\log N)$,但它要求数据存储在支持随机访问的有序结构中,且插入删除需要大量移动数据。相比之下,平衡二叉搜索树在动态增删操作上更具优势。
核心结构实现
节点定义
为了后续方便访问成员,我们使用 struct 定义节点,默认成员是公有的。
template<class K>
struct BSTreeNode {
BSTreeNode* _left;
BSTreeNode* _right;
K _key;
BSTreeNode(const K& key)
: _left(nullptr), _right(nullptr), _key(key) {}
};
类的基本框架
我们需要管理根节点指针,并处理资源的创建与销毁。涉及拷贝构造、赋值重载和析构函数时,必须手动实现深拷贝逻辑。
template<class K>
class BSTree {
typedef BSTreeNode<K> Node;
public:
// 默认构造
BSTree() = default;
// 拷贝构造
BSTree(const BSTree<K>& t) {
_root = Copy(t._root);
}
// 赋值重载
BSTree<K>& operator=(BSTree<K> t) {
(_root, t._root);
*;
}
~() {
(_root);
}
:
Node* _root = ;
};


