平衡二叉树,顺序和O之间的操作(logn)

时间:2015-02-24 14:27:12

标签: algorithm data-structures binary-tree binary-search-tree avl-tree

但是我几天前参加考试时遇到了挑战。

如果我们使用n个顶点平衡二叉树,并在子树中为每个节点存储子节点数(即该节点作为根节点的子节点数)。我们如何在O(log n)中执行这些操作?

1)找到给定元素的顺序。 (即像OS-SELECT(x,i)中的顺序统计树,它找到了以x为根的子树中的第一个最小元素,或者为了更好地理解链接上的第303页CLRS Book,但在本书中作者说这个操作在红黑树上不是AVL)

2)找到给定ab之间的数字(假设为a < b)。

3 个答案:

答案 0 :(得分:2)

1)您要求二叉树中的第N个最小元素。我们需要找到元素,但是我们需要存储更小元素的数量。

每当我们走向正确时,我们都需要计算“我们通过的节点”。例如,我们从根开始然后向右走,然后我们需要在根的左子树中查找子节点的数量,并将其添加到我们当前的“订单计数”。

从变量order开始并将其设置为1.我们正在搜索元素N

while not at N:
  if current == N
    //Need to add the number of left children of N to count.
    count += N.LeftSubTreeCount
    return count
  if current > N
    //We are going left.
    update current
  else 
    //We are going right.
    count += current.LeftSubTreeCount + 1
    update current

此解决方案的时间复杂度为O(log n),因为我们只是在每个步骤中搜索树中具有恒定开销的元素。在平衡二叉树中搜索元素的时间是最坏情况O(log n)。

2)这个最简单的解决方案是利用1)中的功能。但是,由于我们在某个时间间隔内搜索树中的元素数量,我们首先需要找到largest元素,即&lt; = a,将其称为aClosest,smallest元素是&gt; = b,bClos​​est。

在我们找到这些之后,我们可以在树中计算他们的顺序并计算:order(bClosest) - order(aClosest)。在1)中开发的函数的顺序。

此解决方案的时间复杂度也是O(log n)。我们所做的只是寻找元素。我们必须总共搜索4次。我们两次搜索我们想要计算顺序的元素,两次我们在这些元素上运行1)中的函数。然后总复杂度为O(4 * log n) - > O(log n)。如果我们可以修改搜索并在同一次迭代中计算顺序,则可以减少这种情况。

搜索最大元素&lt; = a时,您将需要搜索a。然后会发生两件事:

  1. a在树上。
  2. a不在树上。
  3. 如果是1.那么你很好。但是对于2.你可以通过存储你在路径上遇到的最高值来处理。一个。如果a不在树中,那将是您正在寻找的元素。此搜索的输出是aClosest。

    类似地,当搜索b时,存储最小数字的值&gt;湾

答案 1 :(得分:2)

  

如何找到一个给定元素的顺序?

元素的顺序是它在生成的排序序列上的排名。

如果假设我们在子树中存储子项数,我们可以将 虚拟重量 分配给边。任何边缘向左移动0。任何边缘(x -> Y)向右加权x +1左侧树中的子项数,即count(left(x))+1

现在我们可以修改搜索算法

find(x, node)
  if node is null return error
  if node is x return node
  if node < x return find(x, left(node)) else return find(x, right(node))

通过添加累加器,最初为0

order(x, node, acc)
  if node is null return acc
  if node is x return acc + count(left(x))
  if node < x return order(x, left(node), acc) 
  else return order(x, right(node) , acc + 1 + count(left(node)) )

因为额外的存储count(x)是恒定时间。哪个使rank算法O(log n)

  

找到给定a和b之间的数字(假设a&lt; b)。

  • 如果您指的是元素数量,或者它是order(b) - order(a) + 1
  • 的距离
  • 如果你的意思是枚举它们。在O(log(n))中无法实现。提供证明您只需选择最左边的元素为a,最右边的元素为b,它们之间有n-1个元素。

答案 2 :(得分:1)

对于问题1),您需要创建一个dfs(按顺序遍历)。每次访问节点count++直到找到给定元素时,count都是给定元素的顺序。所以需要 O(n)来查找给定元素的顺序。对于排序数组,我们可以使用二进制搜索在 O(log n)中轻松找到它的顺序,但是对于BST,我们不能这样做,除非向树节点添加其他属性。

<强>更新 我很抱歉没有注意到在搜索之前知道孩子的数量。使用此属性,无需穿越树。你只需要在搜索时计算少于给定元素的节点数。那就是每次去正确的孩子,

count += number(left children) + 1;

然后count的结果是给定元素的顺序。搜索函数的这种修改需要每个函数调用一次,它不会影响搜索的时间复杂度, O(log n)

对于问题2),它与在树中查找给定元素但条件松散相同。您只需修改搜索功能:将if(current_element == given_element) found;更改为if(a < current_element < b) found;。所以时间复杂度与普通搜索相同, O(log n)