我正在寻找全二叉树中给定两个节点(父节点x比子节点2*x和2*x+1)的最低公共祖先的恒定时间实现。
我的问题是树中有大量的节点和许多查询。是否有一种算法,它可以进行预处理,以便在恒定的时间内回答查询。
我查看了LCA using RMQ,但是我不能使用该技术,因为我不能对树中的这么多节点使用数组。
如果知道它是完整的二叉树,并且节点之间的关系如上所述,是否有人能给我快速回答许多查询的算法的有效实现。
我所做的是从两个给定的节点开始,依次找到它们的父节点(node/2)保留访问节点的哈希列表。当我们到达一个已经在散列表中的节点时,该节点将是最低的公共祖先。
但是当有很多查询时,这个算法非常耗时,因为在最坏的情况下,我可能需要遍历30的高度(树的最大高度)才能到达根(最坏的情况)。

最佳答案

编辑:
在o(log(logn))中获取共同祖先的更快方法:-

int get_bits(unsigned int x) {
  int high = 31;
  int low = 0,mid;
  while(high>=low) {
    mid = (high+low)/2;
    if(1<<mid==x)
      return mid+1;
    if(1<<mid<x) {
      low = mid+1;
    }
    else {
      high = mid-1;
    }
  }
  if(1<<mid>x)
    return mid;
  return mid+1;
}

unsigned int Common_Ancestor(unsigned int x,unsigned int y) {

  int xbits = get_bits(x);
  int ybits = get_bits(y);
  int diff,kbits;
  unsigned int k;
  if(xbits>ybits) {
    diff = xbits-ybits;
    x = x >> diff;
  }
  else if(xbits<ybits) {
    diff = ybits-xbits;
    y = y >> diff;
  }
  k = x^y;
  kbits = get_bits(k);
  return y>>kbits;

}

说明:
获取表示x&y所需的位,使用二进制搜索是o(log(32))
x&y二进制表示法的共同前缀是共同的祖先
以较大的位数表示的数字由k>>diff带到同一位
k=x^y eraze x&y的公共前缀
查找表示剩余后缀的位
按后缀位移动x或y,得到共同的前缀,即共同的祖先。
示例:
x = 12 = b1100
y = 8  = b1000

xbits = 4
ybits = 4
diff = 0
k = x^y = 4 = b0100
kbits = 3
res = x >> kbits = x >> 3 = 1

ans : 1

10-04 20:58