【发布时间】:2020-04-24 12:14:02
【问题描述】:
我想要一个在其中插入元素的数据结构,在插入之后,它保持排序状态,我在日志 N 次中找出我刚刚插入的元素的索引。
我尝试过使用向量和多重集,但都不满足这两个要求。
矢量:
如果我想找到一个元素的索引,我可以这样做:
using namespace std;
vector<int>::iterator it = lower_bound(myvec.begin(), myvec.end(), someElement);
int index = (it - myvec.begin());
但是,向量在保持排序时不允许 O(log N) 插入时间。每次插入后对向量进行排序将是 O(N log N)。我试过了:
vector<int>::iterator it = lower_bound(myvec.begin(), myvec.end(), someElement);
myvec.insert(it, someElement);
这会找到插入元素的正确位置,但 myvec.insert 在 O(N) 时间而不是 O(log N) 时间运行。
多组:
多重集允许我插入并保持排序,但它缺乏的是在插入后获取元素的索引。
multiset<int>::iterator it = lower_bound(myset.begin(), myset.end(), someElement);
使用lower_bound后,我不能只做
int index = (it - myset.begin());
就像我使用矢量一样。相反,我考虑的一种方法是:
int index = distance(myset.begin(), it);
但是,距离运行时间为 O(N),而不是 O(log N)。
是否有数据结构或方法可以让我在 log N 时间内同时满足这两个要求?
【问题讨论】:
-
这是一个“有序向量”,插入时间为
O(n):boost.org/doc/libs/1_65_0/doc/html/boost/container/…。实现std::set的O(log n)主要是因为可以在不复制数据的情况下重新排列元素。我认为这对于一个连续的有序容器是不可能的。 -
我正在寻找插入时间为 O(log N) 而不是 O(N) 的有序数据结构。
-
你需要索引做什么?
-
@parktomatomi 容器不需要是连续的,因此可以使用修改后的二叉搜索树来跟踪每个子树中的节点数。这可以轻松更新并用于在遍历期间查找索引。
标签: c++ sorting vector multiset