我想创建一个可以存储角度间隔的数据结构,例如(a,b)
,其中a
和b
表示某个段A,B
的终点的极角1}}针对点Q
此数据结构必须支持两个操作。插入新的间隔,并告诉我是否覆盖了点Q
的整个视点,换句话说,如果段创建的所有视点的并集是360度。
我尝试实现一个非常简单的间隔树,其插入过程如下。
(a,b)
您要插入的间隔。(a,b)
是否完全由存储在根节点中的时间间隔覆盖,如果是这种情况,则返回并不执行任何操作。我没有使用增强数据结构,所以在最坏的情况下插入一个间隔你将不得不进行O(n)
操作,这使得插入O(n^2)
间隔的复杂度为n
。
这是问题所在。使用角度时,必须处理周期,极角为a
,极角为b
。因此,给定一个分段AB
,您会发现终点与Q
的极角,但那么如何找出将存储在树中的间隔?
有人可能会说,你的间隔可以是(min(angleAQ, angleBQ), max(angleAQ, angleBQ))
。
然而,在以下情况下,这不起作用:
间隔将由蓝色角度和绿色角度定义,该角度远大于由红色角度定义的实际视点。
由于这种循环特性,管理这样的角度间隔要困难得多。
我的问题是这样的区间树是否可以存在,如果有的话,有人能给我一些提示来克服这些困难吗?
提前谢谢
答案 0 :(得分:3)
角度的圆度不是主要障碍:而是将[270, 45)
之类的区间包裹起来,而是插入两个区间[270, 360), [0, 45)
。
要实现不包围的插入,我们可以使用二叉搜索树。此树通过将未覆盖间隔的每个端点映射到它是左端点还是右端点来跟踪未覆盖的间隔。例如,如果我们已覆盖间隔[0, 45), [0, 60), [90, 120), [150, 180), [180, 270)
,则映射为
60: left
90: right
120: left
150: right
270: left
360: right .
使用
初始化映射0: left
360: right
要使用[a, b)
插入时间间隔a < b
,我们会执行以下操作。在映射中找到x
的前任a
(最大密钥不大于a
)。如果x
存在并且是左端点,则插入a
作为右端点(在x
之后)。在映射中找到y
的后继b
(最小密钥不小于b
)。如果y
存在并且是正确的端点,则插入b
作为左端点(y
之前)。删除不仅在a
和b
之间插入的所有密钥。当且仅当映射为空时,才会完全覆盖初始间隔。