文章目录
- 前言
- 参考目录
- 学习笔记
- 4:区间搜索树(interval search trees)
- 4.1:一维区间搜索
- 4.2:区间搜索树定义
- 4.3:区间搜索树 demo 演示
- 4.3.1:插入
- 4.3.2:搜索命中
- 4.3.3:搜索未命中
- 4.3.4:搜索代码实现
- 4.3.5:搜索分析
- 4.4:区间搜索树分析
- 5:矩形交集问题(rectangle intersection)
- 5.1:微处理器与几何
- 5.2:算法与摩尔定律
- 5.3:矩形相交查询:扫描线算法
- 5.4:扫描线算法分析
- 6:总结:BST 的几何应用
前言
本篇内容属于《算法》视频的番外篇,是关于前面几篇所学内容 BST 的扩展应用,因此在学习本篇之前,请先学习或回顾一下前面几篇的内容:《3.1 符号表》、《3.2 二叉查找树》、《3.3 平衡查找树》。
温馨提示:如果不知道 BST 是什么的朋友强烈建议先看看前面几个章节的内容。: )
由于本章节的内容很多,所以分成了上下两篇,本篇主要内容包括:区间搜索树、矩形交集问题。
参考目录
- B站 普林斯顿大学《Algorithms》视频课
(请自行搜索。主要以该视频课顺序来进行笔记整理,课程讲述的教授本人是该书原版作者之一 Robert Sedgewick。) - 微信读书《算法(第4版)》
- 官方网站
学习笔记
注 1:所有 demo 演示均为视频 PPT demo 截图。
注 2:如果 PPT 截图中没有翻译,会在下面进行汉化翻译,因为内容比较多,本文不再一一说明。
注 3:由于以下内容是连接上篇的,所以目录也是连贯的,不从 1 开始。
4:区间搜索树(interval search trees)
4.1:一维区间搜索
一维区间搜索。数据结构用于存储一组(可能重叠的)区间。
- 插入一个区间(左端点 lo,右端点 hi)。
- 搜索一个区间(左端点 lo,右端点 hi)。
- 删除一个区间(左端点 lo,右端点 hi)。
- 区间交集查询:给定一个区间(左端点 lo,右端点 hi),在数据结构中查找所有与该区间相交(或至少有一个相交)的区间。
4.2:区间搜索树定义
创建一个 BST,其中每个节点存储一个区间(左端点 lo,右端点 hi)。
- 将区间的左端点作为 BST 中节点的key。
- 在以当前节点为根节点的子树中,存储该子树内所有区间右端点的最大值。
4.3:区间搜索树 demo 演示
4.3.1:插入
要插入一个区间(左端点 lo,右端点 hi):
- 使用左端点 lo 作为key,将其插入到BST中。
- 在搜索路径上的每个节点上更新最大右端点值。
插入区间 (16, 22) :
依次使用区间左端点 16 与各个节点左端点进行比较,直到遇到空链接,最终插入 BST:
(这一步比较简单,不再一一截图,给出路线图)
插入之后,需要检查并更新路径上每个节点的最大值:
4.3.2:搜索命中
要搜索与查询间隔 ( lo, hi ) 相交的任何一个间隔:
- 如果节点中的区间与查询区间相交,则返回。
- 否则如果左子树为空,则向右走。
- 否则如果左子树的最大端点小于lo,则向右走。
- 否则向左走。
搜索区间 (23, 25) :
初始状态:
比较根节点 (17, 19) ,没有相交:
比较左子树最大端点22 < 23,右移:
比较节点 (21, 24) ,相交,搜索命中:
4.3.3:搜索未命中
搜索区间 (12, 14) :
初始状态:
比较根节点 (17, 19) ,没有相交:
左子树不为空,且左子树最大端点 22 > 12,左移:
比较节点 (5, 8) ,没有相交:
比较左子树最大端点8 < 12,右移:
比较节点 (15, 18) ,没有相交:
比较左子树最大端点10 < 12,右移:
比较节点 (16, 22) ,没有相交:
左子树为null,右移:
右子树为null,没有相交点,搜素未命中:
4.3.4:搜索代码实现
4.3.5:搜索分析
案例 1:如果向右搜索,则左侧没有交集。
证明:假设搜索向右且左子树非空。
- 由于向右走,我们有 max < lo。
- 对于x的左子树中的任意区间 (a, b),我们有 b ≤ max < lo
- 因此,(a, b) 不会与 (lo, hi) 相交。
案例 2:如果向左搜索,则左子树中要么存在交集,要么两者都没有交集。
证明:假设左边没有交集。
- 从左边开始,我们有 lo ≤ max。
- 则对于x的右子树中的任意区间 (a,b),hi < c ≤ a ⇒ 右侧无交集。
4.4:区间搜索树分析
使用红黑树保证性能。(易于维护辅助信息)
5:矩形交集问题(rectangle intersection)
5.1:微处理器与几何
20世纪70年代早期,微处理器设计转变成一个几何学问题。
- 超大规模集成电路(Very Large Scale Integration,VLSI)
- 计算机辅助设计(Computer-Aided Design,CAD)
设计规则检查。
- 某些导线不能相互交叉。
- 不同类型的导线之间需要保持特定的间距要求。
- 调试过程 = 正交矩形相交点的搜索。
5.2:算法与摩尔定律
“摩尔定律”:集成电路的集成度(或者说处理器的运算能力)大约每 18 个月翻一番。
- 在 197x 年,需要检查 N 个矩形区域的问题;
- 到了 197(x+1.5) 年,在一台速度提升2倍的计算机上,则需检查 2N 个矩形区域。
自举(Bootstrapping)意味着我们可以利用更快的计算机来设计和验证更大的电路。
(自举的核心思想是指一个系统、过程或算法通过自己的内部机制或有限的基础条件,逐步建立并完善自身的能力或功能。)
但是,仅靠自举是不够的,如果仍然采用二次时间复杂度的算法:
- 在 197x 年,解决 N 个矩形的问题需要 M 天;
- 到了197(x+1.5) 年,(即便使用速度提升2倍的计算机,)处理2N个矩形问题仍需时 (4M) / 2 = 2M天。(!)
归根结底,要维持摩尔定律所描述的计算能力增长趋势,采用线性对数时间复杂度(Linearithmic)的算法是必需的。
5.3:矩形相交查询:扫描线算法
从左至右移动一条垂直扫描线。
- 将矩形左右端点的x坐标作为事件定义。(当扫描线与矩形边界的x坐标重合时,触发相应的事件处理。)
- 使用区间搜索树(如红黑树、AVL树等)来存储并维护当前扫描线上相交的所有矩形集合。(这里的存储基于每个矩形在y轴方向上的区间。)
- 当扫描线扫过一个矩形的左端点时:
- 对该矩形在y轴方向上的区间进行区间搜索操作,查找是否已存在于搜索树中;
- 如果不存在,则将该矩形的y轴区间插入到区间搜索树中。
- 当扫描线扫过一个矩形的右端点时:
- 从区间搜索树中移除该矩形对应的y轴区间。
(可以回顾一下上篇 #2.1
线段相交的扫描线算法)
移动过程:
5.4:扫描线算法分析
命题:扫线算法在一组包含 N 个矩形中找出 R 个交点所需的时间与其大小成比例,即 N log N + R log N。
证明:
- 首先,将所有矩形的x坐标放入优先队列(PQ)或进行排序。(N log N)
- 然后,每当扫描线遇到矩形的左端点时,在一个区间搜索树(ST)中插入该矩形对应的y轴区间。(N log N)
- 当扫描线扫过矩形右端点时,从区间搜索树(ST)中删除对应的y轴区间。(N log N)
- 在整个过程中,针对每个矩形的y轴区间执行区间搜索操作。(N log N + R log N)
结论:扫线算法通过将二维正交矩形的相交搜索问题转化为一维区间搜索问题,从而降低了问题的复杂性。
6:总结:BST 的几何应用
(完)