到目前为止,我知道像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)。