我被要求创建一个数据结构,其中插入节点和查找具有特定键值的节点等功能需要O(logn)。 我被要求在O(1)时间内找到中位数。
我一直在考虑使用订单统计树,会选择N / 2等级的节点找到中位数吗?
我在这里看到了类似的问题,但我想要一个更好的解释:(Find median in O(1) in binary tree)
有什么想法吗?
感谢。
答案 0 :(得分:0)
是的,ceil(n / 2)位置(从1开始)的元素确实是中位数(假设序列的大小是奇数)。但是,使用订单统计树来查找某个第k个位置的元素是O(lg n),而不是O(1)。
你应该知道的是:给定一个完美的二叉搜索树(一个二元搜索树,其中所有内部节点都有两个子节点,所有叶子具有相同的深度或相同的级别),中位数正好是根。更一般地说,如果你有一个二叉搜索树结构,其中每个节点也存储其子树中的节点数,并且发生根的左右子节具有相同的数字,则根是中位数。这种情况非常有限,因此一个想法是平衡二叉搜索树,以增加根作为中位数的概率。
另一个想法是:保留一个二叉搜索树和一个额外的变量(指针),指示中位数现在的位置。然后,对于每个插入/删除操作,更新此指针。
希望有所帮助!
答案 1 :(得分:0)
我相信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 )。现在我们不能使用这种方法来查找任何第k个值,就像我们可以使用RB树一样,但对于一个特定的k值,您将在恒定时间内检索其值。此过程也在此paper中引用,它具体说明了在固定时间内检索第k个值的能力。