二叉搜索树概述
看完你能讲清 BST 不变量、复述各操作复杂度,并识别退化陷阱
按 空格/→ 演示下一步
全部页面点击任意一页,跳回舞台从这页播放
二叉搜索树概述
看完你能讲清 BST 不变量、复述各操作复杂度,并识别退化陷阱
什么是二叉搜索树
翻字典时,你不会从第一页逐字找,而是打开中间页,对比词条决定往前还是往后翻——这种「每次砍掉一半」的思路,正是BST在做的事。
每次猜中间值,根据「大了/小了」决定下次往左半还是右半砍
BST的数学定义
从任意一个节点出发,看它的左右子树必须满足什么关系。
BST解决什么问题
前几页我们看了 BST 的结构定义和数学性质,但为什么要把数据塞进这种树里?先回到一个朴素的问题:一堆杂乱的数据,如何在毫秒级内找到某个值?
主持人喊「大了」或「小了」,每次砍掉一半,BST 每层也是这样分流
有序性详解
前面我们说 BST 高效查找靠的是'左小右大'。这条规则还藏着一个意外奖励:按'左→根→右'遍历一次,输出的序列天然升序——仿佛内置了排序。
左子树=A开头的书,右子树=Z开头的书,从左到右扫一遍即升序
有序性验证
用具体例子图解中序遍历如何揭示BST的有序结构
单调性详解
前面用中序遍历检查整棵树,得到从左到右的关键码序列。现在把视角缩到一条根到节点的路径:每向下一层,关键码都必须更大,这就是路径单调性。
文件夹每向下一层编号更大,对应路径后一个关键码更大
单调性验证
沿任意路径追踪:每步比较相邻 key 的大小,看单调是否被守住。
循关键码查找过程
BST 的查找就是从根出发、一路向下比对,每步至少砍掉一半候选。
查找算法图解
从根8出发,每访问一个节点就与目标13比较,根据大小关系决定向左还是向右走,直到命中。
插入操作要点
查找是「问路」,插入是「盖房」——沿问路找到的空地,把新节点作为叶子挂上去,不打乱左右邻居关系。
翻页比较决定左翻右翻,直到空白页落下新词
查找与插入代码
BST 查找与插入的 C++ 实现:查找用 while 迭代下沉,插入递归到空位再挂新节点。
高亮行把「有序性」直接翻译成控制流:一次比较决定下沉方向,递归走到 nullptr 才 new,保证新节点一定挂在能维持左小右大不变的位置。
BST接口概览
上一页我们刚把查找和插入的代码写完。但 BST 对外接口不止这两个——它要回答四类问题。这一页先把它们的语义边界划清楚。
查联系人对应查询;新号码对应插入;删联系人对应删除;按字母列出对应遍历
接口层次结构
BST 接口按依赖关系分两层:底层是关键码比较与有序性,上层是查询、更新与有序操作。
BST vs 数组
都是高效查找结构,但改造成本与适用场景截然不同。
- 二分查找 O(log n)
- 插入/删除需 O(n) 搬移
- 连续内存,缓存极其友好
- 查找平均 O(log n),最坏退化为 O(n)
- 插入/删除平均 O(log n),无需搬移
- 指针连接,原生支持动态增删
自测题
二叉搜索树的核心性质中,对任意节点 u,下面哪条最准确地刻画了它与左子树的关系?
本章小结
- ✓BST本质是「左小右大」的递归结构,关键码决定分支走向
- ✓有序性(中序)与单调性(查找路径)是BST的两条命脉
- ✓复杂度都挂在树高h上:理想O(log n),退化O(n)
- ✓BST是接口而非实现——语义已定,平衡策略另议
- ✓BST以对数级动态操作换取随机访问能力
课后思考
先自己认真想一会儿,再翻参考答案。三题对应回顾、应用、迁移——把最纠结的那个留在脑子里继续转。
参考答案放左/右子树时,'查找应返回哪个等值节点'变得不确定;用计数器(multiset)则语义清晰但节点结构变复杂。取舍取决于应用需要'包含语义'还是'去重语义'。
参考答案插入有序序列时,每个新节点只能往单方向延伸,BST 退化成链表,查找退化为 O(n)。避免思路:插入前随机打乱顺序,或改用 AVL/红黑树等平衡结构。
参考答案中序有序来自'左子树 < 根 < 右子树'的递归约束,不是所有二叉树都有,普通二叉树中序遍历是无序的。放宽为'≤'也仍有序——因为不变量没被打破。