【发布时间】:2017-11-13 07:35:58
【问题描述】:
我被要求创建一个数据结构,其中插入节点和查找具有特定键值的节点等功能需要 O(logn)。 我被要求在 O(1) 时间内找到中位数。
我一直在考虑使用顺序统计树,选择具有 N/2 等级的节点会找到中位数吗?
我在这里看到了一个类似的问题,但我想要一个更好的解释:(Find median in O(1) in binary tree)
有什么想法吗?
谢谢。
【问题讨论】:
标签: median red-black-tree
我被要求创建一个数据结构,其中插入节点和查找具有特定键值的节点等功能需要 O(logn)。 我被要求在 O(1) 时间内找到中位数。
我一直在考虑使用顺序统计树,选择具有 N/2 等级的节点会找到中位数吗?
我在这里看到了一个类似的问题,但我想要一个更好的解释:(Find median in O(1) in binary tree)
有什么想法吗?
谢谢。
【问题讨论】:
标签: median red-black-tree
我相信 Enzo Nakamura 说找到第 k 个位置是 O(log n) 时所指的是使用 red-black binary search tree 和 certain twist。在每个节点上,您还存储该节点的子树的大小。这样,您可以利用二叉搜索树的属性来查找 O(log n) 中的第 k 个值。但是,二叉搜索树的根节点只有在 a) 节点数为奇数且 b) 完美平衡树的情况下才能保证为中值,并且红黑二叉搜索树是不一定完全平衡,因此即使上述方法也不能保证这一点。
有一个著名的问题叫做“running median”,你从中位数开始,然后每次给你一个新元素时都必须计算新的中位数。您可以通过创建一个堆来解决这个问题,该堆的根是中位数,左子树是最小堆,右子树是最大堆。插入这个堆需要 O(log n) 时间,但是一旦创建树,中值检索总是 O(1),因为该结构保证根节点在所有情况下都是中值。
我认为应该可以将这个问题推广到恒定时间内找到第k个值,只要k不变。在运行中位数问题中,每次一个比另一个大 2 个节点时,我们需要重新平衡左右子树。我们可以将这个问题概括为,每次它的大小超过 k 时,我们重新平衡左子树(如果它是第 k 个最小的)或右子树(如果它是第 k 个最大的),插入时间和重新平衡时间仍然都是 O(log n )。现在我们不能像使用 RB 树那样使用这种方法来查找任何第 k 个值,但是对于一个特定的 k 值,您将在恒定时间内检索它的值。这个过程在这个paper中也有引用,具体说明了可以在恒定时间内检索第k个值的能力。
【讨论】:
是的,ceil(n/2) 位置上的元素(从 1 开始)确实是中位数(假设序列的大小是奇数)。但是,使用顺序统计树来查找某个 k-th 位置的元素是 O(lg n),而不是 O(1)。
你应该知道的是:给定一棵完美的二叉搜索树(一棵二叉搜索树,其中所有内部节点都有两个子节点,并且所有叶子都具有相同的深度或级别),中位数正好是根。更一般地,如果您有一个二叉搜索树结构,其中每个节点还存储其子树中的节点数,并且恰好根的左右子节点具有相同的数字,则根是中位数。这种情况非常有限,因此一个想法是平衡二叉搜索树以增加根为中位数的概率。
另一个想法是:保留一个二叉搜索树和一个额外的变量(指针)来指示现在的中位数在哪里。然后,对于每个插入/删除操作,更新此指针。
希望有帮助!
【讨论】: