你需要扩展数据结构,否则无法获得由树组成的数字之间最小间隙的O(1)搜索。
你还有额外的限制,即不增加插入/删除/搜索函数的时间复杂度,并且我假设您也不想增加空间复杂度。
考虑一个通用节点r,它具有左子树r.L和右子树r.R;我们将在节点r中扩展信息,添加一个称为r.x的附加数字,其定义为以下值之间的最小值:
- (仅当r.L不为空时)r值和r.L上最右侧叶子的值
- (仅当r.L深度大于1时)r.L根节点的x值
- (仅当r.R不为空时)r值和r.R上最左侧叶子的值
- (仅当r.R深度大于1时)r.R根节点的x值
(如果没有一种先前的条件有效,则为未定义,在叶节点的情况下)
此外,为了快速插入/删除,我们需要在每个内部节点中添加其左侧和右侧叶节点的引用。
您可以看到,通过这些添加:
- 空间复杂度仅增加一个常量因子
- 插入/删除函数需要更新每个更改的子树的根的x值和最左侧和最右侧的叶子,但可以轻松实现,不超过O(log(n))
- 树根的x值是函数需要返回的值,因此您可以以O(1)实现它
树中的最小间隙是根节点的x值,更具体地说,对于每个子树,仅在子树元素中考虑的最小间隙是子树根部的x值。
这个陈述的证明可以通过递归来进行:
考虑一个以节点r为根的树,其具有左子树r.L和右子树r.R。
归纳假设是r.L和r.R x值的根是子树中节点值之间最小间隙的值。显然,只有按值排序列表中相邻的节点对才能找到最小间隙;由r.L节点存储的值组成的对的最小间隙在r.L根的x值中,考虑右子树时也是如此。鉴于(r.L中任何节点的值)< r.L根节点的值 <(r.R中任何节点的值),未考虑的唯一相邻值对是两个:
- 由根节点值和较高r.L节点值组成的一对
- 由根节点值和较低r.R节点值组成的一对
根据AVL树的性质,具有较高值的r.L节点是其最右侧的叶子节点,而具有较低值的r.R节点是其最左侧的叶子节点。
将r x值赋为四个值(r.L root x value、r.R root x value、(r-r.L root)gap、(r-r.R root)gap)之间的最小值,与分配整个树中相邻节点值之间较小的差距相同,相当于任何可能的节点值对之间更小的差距。
其中一个或两个子树为空的情况是微不足道的。
对于仅由一个或三个节点构成的树的基本情况,很容易看出树根的x值是最小差值。