文章目录
一、基本BST的应用
1. 1-d range search
- 目标
在有序symbol table中扩展实现两个操作:
· Range search: find all keys between k1 and k2.
· Range count: number of keys between k1 and k2.
几何解释:
。。。。。。 || 。。。。 || 。。。。。。。。
一串keys中,找到在某个区间内的keys。
该操作可以应用于数据库,例如查询 收入在1000-5000之间的人有多少,都是谁等。
- 实现
2. 线段交点
- 目标
一个区域内,有许多条水平的线段和垂直的线段,找到它们的交点
- 实现
主要思路是:
先将所有线段按照x坐标升序排好序;
再从左开始扫描,遇到水平线的左端点,将左端点的y坐标加入BST;遇到水平线的右端点,将该线段的左端点的y坐标从BST中移除;
遇到垂直线段,则使用第一个应用中的range search方法,查找范围为垂直线段两端点的y坐标之间,查找BST中该范围内的所有y坐标。
- 复杂度NlogN
二、kd-trees
1. 2-d range search
- 目标
在二维空间中实现range search 和 range count。
平面内有许多点,找到平面内位于某个特定矩形范围内的所有点。
该应用也可以应用于数据库,比如找到年龄20-30岁之间且收入1000-5000之间的人。
- 实现
实现共分为两步:
- 首先构建2-d tree
主要思路是,每个点都作垂直线或者水平线,将区域分成两部分。从点1开始,做垂直线,将区域分成左右两部分,对应在2-d tree中点1的左子树为点1左边的点,右子树为点1右边的点。接着,点2在点1右侧,所以点2成为点1的右子节点;经过点2作水平线,将点1右侧的空间分割成上下两部分,对应在2-d tree中,点2的左子树为点1右侧点2上侧的空间,点2的右子树为点1右侧点2下侧的空间。点3同样将点1的左侧空间分割成两部分。以此类推,将整个平面划分成不同的区域。
- 然后进行2-d range search
从root开始,目标区域在点1左侧,所以进入左子树。目标区域在点3的上下侧都有,所以左右子树都要去。以此类推。
2. 2-d 最近点搜索
2-d tree的另一个应用:
在平面中给定一个点k,找到已经存在的点中与其最近的点。
typical case:logN; worst case:N
3. kd-tree
kd tree可以解决k维的问题。仍然使用BST,将k维拆成多个2维。(似乎是这个意思)
三、interval search trees
1. 定义
该树是由BST衍生而来的。该树的节点中存储的都是区间,主要目的是判断给定的区间和树种哪些区间有交集。
2. 实现
- 搭建interval search tree
- insert
・Insert into BST, using lo as the key.
・Update max in each node on search path.
例如上图中,插入(16, 22),以16为key,找到其插入位置为(15,18)的右子节点。插入后,再原路返回更新每个节点的max endpoint。
- search
Node x = root;
while (x != null)
{
if (x.interval.intersects(lo, hi)) return x.interval;
else if (x.left == null) x = x.right;
else if (x.left.max < lo) x = x.right;
else x = x.left;
}
return null;
证明search的正确性:
3. 复杂度
4. 区间搜索树的应用: 矩形相交
- 目标:找到矩形相交的位置
该问题可以应用于例如电路设计,在电脑上设计电路时,一些线路围成的矩形是不能相交的,可以检测这些线路是否相交。
- 实现
与线段交点的检测类似,只不过将基本BST换成了区间搜索树。每次扫描到矩形的左边缘时,先进行区间搜索,检测该边的y坐标区间与树中的区间是否有重合,并将该边的y坐标区间存在区间搜索树中。扫描到右边缘,则在树中删除该矩形左边缘的y坐标区间。
- 复杂度