(a)概述

官方信息技术老师·18 页·深入(追求细节与边界)·0 次浏览·2 天前
BST不变量复杂度分析边界情况

二叉搜索树概述

看完你能讲清 BST 不变量、复述各操作复杂度,并识别退化陷阱

按 空格/→ 演示下一步

1 / 18 页

全部页面点击任意一页,跳回舞台从这页播放

BST不变量复杂度分析边界情况

二叉搜索树概述

看完你能讲清 BST 不变量、复述各操作复杂度,并识别退化陷阱

1第 1 页 · 二叉搜索树概述

什么是二叉搜索树

翻字典时,你不会从第一页逐字找,而是打开中间页,对比词条决定往前还是往后翻——这种「每次砍掉一半」的思路,正是BST在做的事。

大小有序
每个节点左子树所有值更小,右子树所有值更大
递归成立
左、右子树自身也必须满足同样的大小关系
节点唯一
通常不允许重复值;等于的情况视实现而定
猜数字游戏对应 →BST查找过程

每次猜中间值,根据「大了/小了」决定下次往左半还是右半砍

2第 2 页 · 什么是二叉搜索树

BST的数学定义

从任意一个节点出发,看它的左右子树必须满足什么关系。

图解渲染中…
a1当前考察的节点,其键值为 kb1左子树里所有节点的键值都严格小于 kc1右子树里所有节点的键值都严格大于 kd1递归:左、右子树自身也必须是 BST
3第 3 页 · BST的数学定义

BST解决什么问题

前几页我们看了 BST 的结构定义和数学性质,但为什么要把数据塞进这种树里?先回到一个朴素的问题:一堆杂乱的数据,如何在毫秒级内找到某个值?

无序的痛点
只能从头扫到尾,一万条数据最坏要扫一万次
有序的二分快
排好序后二分查找,每步砍一半,一万条约 13 步
有序的插入慢
插入新数据要挪动后续所有元素,最坏也要挪一万次
BST 兼顾两边
查找、插入、删除均摊 O(log n),动态数据的最优解
猜数字游戏对应 →BST 的查找过程

主持人喊「大了」或「小了」,每次砍掉一半,BST 每层也是这样分流

无序数组=O(n)有序二分=O(logn)BST 均摊=O(logn)\text{无序数组} = O(n) \quad \text{有序二分} = O(\log n) \quad \text{BST 均摊} = O(\log n)
4第 4 页 · BST解决什么问题

有序性详解

前面我们说 BST 高效查找靠的是'左小右大'。这条规则还藏着一个意外奖励:按'左→根→右'遍历一次,输出的序列天然升序——仿佛内置了排序。

中序遍历顺序
左子树 → 根 → 右子树,递归处理每一层
左右子树天然分块
左子树全部小于当前节点,右子树全部大于
全局升序输出
层层递归,自然从最小键值一路访问到最大键值
序列与树形无关
同一组键值的不同 BST 形态,中序序列始终唯一
图书馆按 A→Z 排列的整面书墙对应 →BST 的中序遍历

左子树=A开头的书,右子树=Z开头的书,从左到右扫一遍即升序

5第 5 页 · 有序性详解

有序性验证

用具体例子图解中序遍历如何揭示BST的有序结构

有序性验证
用具体例子图解中序遍历如何揭示BST的有序结构
6第 6 页 · 有序性验证

单调性详解

前面用中序遍历检查整棵树,得到从左到右的关键码序列。现在把视角缩到一条根到节点的路径:每向下一层,关键码都必须更大,这就是路径单调性。

中序全局有序
中序是左—根—右,键互异时得到严格递增的整树序列
根到节点递增
每向下一层关键码都更大;各步的不等关系可传递到整条路径
比较有边界
同层节点或不同分支的节点,不能据此直接比较大小
重复键约定
若允许相等,路径上只能写非递减;放置规则必须统一
按编号深入的文件夹对应 →BST的根到节点路径

文件夹每向下一层编号更大,对应路径后一个关键码更大

x0=root,xi+1{L(xi),R(xi)},xi.key<xi+1.keyx0.key<<xk.keyx_0=\mathrm{root},\quad x_{i+1}\in\{L(x_i),R(x_i)\},\quad x_i.key<x_{i+1}.key\Rightarrow x_0.key<\cdots<x_k.key
7第 7 页 · 单调性详解

单调性验证

沿任意路径追踪:每步比较相邻 key 的大小,看单调是否被守住。

图解渲染中…
b1向右走 → key 必须严格递增b2向左走 → key 必须严格递减e1一旦违反,整条路径非合法 BST 路径
8第 8 页 · 单调性验证

循关键码查找过程

BST 的查找就是从根出发、一路向下比对,每步至少砍掉一半候选。

1
从根出发
每次查找都从根节点起步,不存在其他入口
2
与当前节点比较
把目标 key 与当前节点 key 比大小
3
按大小选左右
小于走左子树,大于走右子树,缩小候选范围
4
命中或落空
相等则找到;遇到空指针则查找失败
9第 9 页 · 循关键码查找过程

查找算法图解

从根8出发,每访问一个节点就与目标13比较,根据大小关系决定向左还是向右走,直到命中。

图解渲染中…
a1矩形:访问某个树节点q1菱形:一次大小比较判断e1NIL:空子树,未命中即返回
10第 10 页 · 查找算法图解

插入操作要点

查找是「问路」,插入是「盖房」——沿问路找到的空地,把新节点作为叶子挂上去,不打乱左右邻居关系。

沿查找路径定位
复用查找逻辑,比关键码大小决定左走或右走,遇空即停
新节点必为叶子
空指针处挂载,不会替换或上提已有节点
原树结构不变
路径上节点相对位置不动,只新增一条根到叶的链
重复键需约定
相等放左或右须实现时定死,多数库放右或拒绝
字典里按字母插入新词对应 →BST 插入节点

翻页比较决定左翻右翻,直到空白页落下新词

insert(T,k)={new Node(k)T=insert(T.left,k)kT.keyinsert(T.right,k)k>T.key\text{insert}(T,k) = \begin{cases} \text{new Node}(k) & T=\varnothing\\ \text{insert}(T.\text{left},k) & k\leq T.\text{key}\\ \text{insert}(T.\text{right},k) & k> T.\text{key} \end{cases}
11第 11 页 · 插入操作要点

查找与插入代码

cpp

BST 查找与插入的 C++ 实现:查找用 while 迭代下沉,插入递归到空位再挂新节点。

代码高亮加载中…

高亮行把「有序性」直接翻译成控制流:一次比较决定下沉方向,递归走到 nullptr 才 new,保证新节点一定挂在能维持左小右大不变的位置。

12第 12 页 · 查找与插入代码

BST接口概览

上一页我们刚把查找和插入的代码写完。但 BST 对外接口不止这两个——它要回答四类问题。这一页先把它们的语义边界划清楚。

查询
给定关键码,找到节点或判定不存在
插入
把新关键码塞到合适位置,仍保持有序
删除
移除目标节点,用替补填补空位
遍历
按特定顺序访问全部节点,中序即升序
手机通讯录对应 →BST 四大接口

查联系人对应查询;新号码对应插入;删联系人对应删除;按字母列出对应遍历

13第 13 页 · BST接口概览

接口层次结构

BST 接口按依赖关系分两层:底层是关键码比较与有序性,上层是查询、更新与有序操作。

图解渲染中…
a1所有操作的共同基础:比较两个关键码b1查找定位:确定关键码所在位置b2有序性:BST 隐含的升序结构c2更新操作必须先经过查找定位
14第 14 页 · 接口层次结构

BST vs 数组

都是高效查找结构,但改造成本与适用场景截然不同。

有序数组
  • 二分查找 O(log n)
  • 插入/删除需 O(n) 搬移
  • 连续内存,缓存极其友好
二叉搜索树
  • 查找平均 O(log n),最坏退化为 O(n)
  • 插入/删除平均 O(log n),无需搬移
  • 指针连接,原生支持动态增删
数据静态、查多改少选有序数组;频繁增删且能维持平衡,选BST。
15第 15 页 · BST vs 数组

自测题

点击作答

二叉搜索树的核心性质中,对任意节点 u,下面哪条最准确地刻画了它与左子树的关系?

16第 16 页 · 自测题

本章小结

  • BST本质是「左小右大」的递归结构,关键码决定分支走向
  • 有序性(中序)与单调性(查找路径)是BST的两条命脉
  • 复杂度都挂在树高h上:理想O(log n),退化O(n)
  • BST是接口而非实现——语义已定,平衡策略另议
  • BST以对数级动态操作换取随机访问能力
延伸主题:平衡BST:AVL与红黑树如何控树高BST的删除操作:边界处理更复杂区间查询:利用有序性的进阶玩法
17第 17 页 · 本章小结

课后思考

先自己认真想一会儿,再翻参考答案。三题对应回顾、应用、迁移——把最纠结的那个留在脑子里继续转。

1BST 允许重复 key 时怎么处理?放左子树、放右子树、用计数器——三种策略对查找和删除语义各有什么影响?

参考答案放左/右子树时,'查找应返回哪个等值节点'变得不确定;用计数器(multiset)则语义清晰但节点结构变复杂。取舍取决于应用需要'包含语义'还是'去重语义'。

2插入序列若有序(如 1,2,...,n),BST 会退化成什么?查找复杂度从 O(log n) 退化成多少?怎么避免?

参考答案插入有序序列时,每个新节点只能往单方向延伸,BST 退化成链表,查找退化为 O(n)。避免思路:插入前随机打乱顺序,或改用 AVL/红黑树等平衡结构。

3BST 的中序遍历天然得到有序序列——这是 BST 独有的性质,还是所有二叉树都满足?定义放宽后还成立吗?

参考答案中序有序来自'左子树 < 根 < 右子树'的递归约束,不是所有二叉树都有,普通二叉树中序遍历是无序的。放宽为'≤'也仍有序——因为不变量没被打破。

18第 18 页 · 课后思考