【计算几何 第10章】更多几何数据结构:截窗

本文涉及知识点

数学 几何

预备知识

求小于a的数的数量

下面是伪代码

cpp 复制代码
int i=0;
for(;(i<xs.size())&&(xs[i]<a));i++);

如果xs是升序排序,代码执行结束后xs的钱i个元素就是全部小于a的数。时间复杂度:O(k+1),k是xs中小于a的元素的数量。

快速排序

选择一个标兵(主元素pivot),将小于标兵的值放到left中,其余值放到right中。对left,right分别进行快速排序。

最佳时间复杂度和平均时间复杂度都是O(NlogN),递归logN层,每层递归,任意元素排序且仅排序一次。最坏O(NN)。

空间复杂度:O(NlogN),可以优化到O(logN)。

最简单的实现,标兵是首元素或尾元素。这样会有问题:对于已经升序或降序,left和right 有一个为空。

改进的方式:

一,随机选择。

二,(最小值+最大值)/2。

三,中位数的中位数。

四,三数取中,首元素中间元素尾元素的平均值。

极端情况:数值全部相同也可能有问题。

中位数的中位数

将所有的数分成5个一个组,排序。arr 收集各组的中位数,第arr求中位数的中位数。最终结果在30%到70%分位,无法保证刚好是中位数。令最终结果是y,则有一半的初始组 ≥ y \ge y ≥y,这些组至少3个元素 ≥ y \ge y ≥y,故至少30%的元素小于y。

堆排序

插入删除元素时间复杂度O(logN)。空间复杂度O(n)。由于是满二叉树,故最多logN层,每层只会改变一个节点。小根堆,只需要保证各子树根节点最小,兄弟节点的大小关系不限。

快速选择算法(Quickselect)

从未排序数组中选择最小的k个元素,是快速排序的变种。快速选择算法的平均时间复杂度是 O(N),但最坏情况下的时间复杂度是 O(N^2) ,所以要随机化。

容易理解的版本:

选择标兵,将小于标兵的值放到left中,其它值放到right中。

如果left.size等于k,left就是答案。

如果left.size>k,快速选择(left,k)。

如果left.size()< k,left的全部元素是答案,快速选择(right,k-left.size())。

每次递归都只需要处理left或right,而每次调用left和right的期望长度减半。

从堆中选择<a的所有数

如果堆的根节点<a,将根节点放到结果中,递归处理左右子节点。

如果堆的根节点 ≥ a \ge a ≥a中,返回。

空间复杂度:O(N)

时间复杂度:O(K)

如果一个节点<a,则一定会被处理到。

如果一个节点任意祖先 ≥ a \ge a ≥a,它不会被处理到。

节点 ≥ a \ge a ≥a,父节点<a的节点数不会超过2k。

1 线段树(原书第三节)

刷力扣和洛谷图时,研究过,就不赘述了。

2 优先查找树

离线查询查询区域的点

已知二维点集,各点x,y各不相同,如果相同,可以用合成数进行预处理。将四维查询Q=(left,top,right,bottom)拆成两个三维查询Q1=(left,top,bottom),Q2=(right,top,bottom),则Q=Q2-Q1。将三维查询放到datas中,按x的升序排序。

依次处理datas,

将x小于等于datasi.x的坐标放到二叉树中set,it1=set.lower(top),it2= set.upper(bottom), it1,it2之间的点是全部答案。

优先查找树

如果强制在线,则上述方法失效。

优先查找树是小根堆,即任意子树根节点pt.x最小。性质一

任意子树,除根节点外的节点,按下述标准拆分左右子树:按(y,x)排序,前半部分属于左子树,右半部分属于右子树。

性质二 :根节点是root,则左子树left的节点的y ≤ y 1 ≤ \le y1 \le ≤y1≤ 右子树right的节点的y。left的左右节点是left1,left2,则

− ∞ < l e f t 1. y ≤ y 2 ≤ l e f t 2. y ≤ y 1 -\infty < left1.y \le y2 \le left2.y \le y1 −∞<left1.y≤y2≤left2.y≤y1。right的左右节点是right1,right2。则 y 1 ≤ r i g h t 1. y ≤ y 3 ≤ r i g h t 2. x < + ∞ y1 \le right1.y \le y3 \le right2.x < +\infty y1≤right1.y≤y3≤right2.x<+∞

对子树T,查询Q,top,right,bottom。

如果T的根节点.pt.x > right retrun

如果pt.y在left,right之间,将pt放到结果中。

如果yMid不在Q中,则只需要处理一个节点。

如果yMid在Q中,则需要处理两个节点,新的查询Q1,Q2和对应节点的上边界或下边界相等。

如果Q和T的上(下)边界相等,不失一般性,令上边界相等。

如果下边界相等,则无需处理右节点。

如果查询的右边界对于节点的右边界,则右节点正常处理。左节点,取所有小于right的点。

如果查询的右边界小于节点的右边界,则左节点正常处理。

结论 :任意层要么处理一个节点。要么处理两个节点,但这两个节点的边界和子查询的一个边界重合。

故时间复杂度:O(K+logN)。空间复杂度:O(N)

3 区间树(原书第一节)

查询和某矩形有交点的水平或垂直线段。许多书籍线段树和区间树是同一个东西,本章讲解的区间树不是线段树。

线段的一个或两个端点在矩形内

利用分散层叠技术优化二维树后,可以在O(LogN+k)的时间内,查询指定区域的点。

引理10.1:设S为平面上一组共n条与坐标轴平行的线段。对于任一与坐标轴平行的查询窗口,我们都可在O(logn+k)时间内,将至少有一个端点落在该查询窗口内的线段报告出来:为此需要设计一个占用O(nlogn)空间的数据结构,其预处理时间为O(nlogn)。其中,k为实际报告出来的线段条数。

N条已知线段S,求和未知垂直直线L相交的线段

由于L是垂直直线,故可忽略线段的y。S共有2N个线段端点,xMid 是这些端点中位数x。线段的右端点<xMid,放到left;线段的左端点> xMid,放到right;其它放到mid。

令L:= x=x',则

如果x'<mid,无需处理right; 递归处理left;mid中的线段右端点 ≥ x m i d > x ′ \ge xmid >x' ≥xmid>x′,预处理时对mid线段的左端点按升序排序,可在常数时间得到这些点。

如果x'=mid,mid就是答案。

如果x'>mid,无需处理left;递归处理right;mid中的线段左端点 ≤ x m i d < x ′ \le xmid <x' ≤xmid<x′,预处理时对mid线段右端点按降序排序,可在常数时间内得到这些点。

由于xMid是端点x的中位数,故left和right顶多有N个端点,即最多N/2条线段。故所有层次的节点数 ≤ N + N / 2 + N / 4 + N / 8 ⋯ < 2 N \le N+N/2+N/4+N/8 \cdots<2N ≤N+N/2+N/4+N/8⋯<2N

故时间复杂度是:O(K+LogN)

定理10.4:给定一组共n个区间I,其对应的区间树占用O(n)空间,而且能够在O(nlogn)时间内构造出来。对于任意待查询点,都可以借助区间树,在O(logn+k)时间内将包含改点的所有区间报告出来,其中k为实际被报告出来的区间数目。

线段与矩形相交但两个端点都在矩形之外

分两种情况:线段与矩形的左右边界相交;线段与矩形的上下边界相交。xy互换后,其实是一种情况。

我们将区间树扩展一下,使得可以针对垂直线段。left和right处理相同。mid的处理略有不同,以x'<xmid为例。如果线段的左端点在以下区域,则与待查线段L相交:L的左边,L.x1的下边,L.x2的上边。用2维KD树或区域树解决。

扩展阅读

算法为骨,CAD为魂
请通过博文下载学院导航
经典文章推荐:C++BFS算法
活到老,学到老。明朝中后期,大约50%的进士能当上堂官(副部及更高);能当上堂官的举人只有十余人。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。

测试环境

操作系统:win7 开发环境: VS2019 C++17

或者 操作系统:win10 开发环境: VS2022 C++17

如无特殊说明,本算法用**C++**实现。

相关推荐
啦啦啦啦啦zzzz1 小时前
升序链表的定时器
linux·服务器·网络·数据结构·c++·链表
WBluuue1 小时前
数据结构与算法:带权并查集
数据结构·c++·算法
熊猫_豆豆1 小时前
黑洞的粒子产生(霍金1975年论文)第二部分
人工智能·数学·算法·机器学习·量子力学·大学物理·黑洞
kkkkkkkkkk_Z9 小时前
学嵌入式和C语言编程数据结构|学习日记Day22:栈,二叉树,哈希存储
c语言·数据结构·学习
码行山野赴时序归途9 小时前
三道经典数组题:从暴力到最优的算法思维
c语言·开发语言·数据结构·算法·leetcode
码行山野赴时序归途14 小时前
算法效率的度量(上):时间复杂度中的对数思维
c语言·数据结构·算法
一木 之林16 小时前
四、STL容器与数据结构
开发语言·数据结构·c++
_Narcissus_17 小时前
二分算法笔记及例题
数据结构·c++·笔记·算法·蓝桥杯·查找·二分算法
万法若空19 小时前
CSP-J/S 排序算法完整专题训练题单
数据结构·算法·排序算法