用于插入/删除/排名/选择查询的最佳数据结构/算法



到目前为止,我知道像AVL树和红黑树这样的自平衡BST可以在O(log n)时间内完成这些操作。

但是,要使用这些结构,我们必须自己实现 AVL 树或 RB 树。

我听说这四个操作有一个算法/实现,不使用自平衡BST。

有了我们自己定义的结构,我们需要写这么多行。但是,我听说有可能在不到 100 行的代码中支持这四个运算符:\

你们对如何做到这一点有什么想法吗?

除了BST,还有其他可能的选择吗?

如注释中所述,如果要维护一组整数,并且可以执行坐标压缩作为预处理步骤(例如,因为您的算法是离线的并且知道所有未来的查询),则可以使用二进制索引树来支持在O(log n)中插入/删除/排名/选择每个操作中的数字。下面是 C++ 中的一个示例:

int tree[N];  // where N is the number of compressed coordinates
const int maxl = floor(log(N)/log(2));
void insert(int i) { // 1 <= i <= N
  for (; i <= N; i += i & -i) ++tree[i];
}
void remove(int i) { // 1 <= i <= N
  for (; i <= N; i += i & -i) --tree[i];
}
int rank(int i) { // 1 <= i <= N
  int sum = 0;
  for (; i; i -= i & -i) sum += tree[i];
  return sum;
}
int select(int k) { // k is 1-based
  int ans = 0, s = 0;
  for (int i = maxl; i >= 0; --i) // maxl = largest i s.t. (1<<i) <= N
    if (s + tree[ans + (1<<i)] < k) {
      ans += 1<<i;
      s += tree[ans];
    }
  return ans+1;
}

select功能有点神奇。它重用更高位的结果来计算 O(1) 中 ans + (1<<i) 的前缀和,恕我直言,这很酷:)这样,它只需要时间O(log n),而不是使用标准二进制搜索很容易实现的O(log^2 n)。

最新更新