【问题标题】:Data structure that stays sorted, allows log N insertion time, and can return the index of an element that I look for in log N保持排序的数据结构,允许 log N 插入时间,并且可以返回我在 log N 中查找的元素的索引
【发布时间】: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::setO(log n) 主要是因为可以在不复制数据的情况下重新排列元素。我认为这对于一个连续的有序容器是不可能的。
  • 我正在寻找插入时间为 O(log N) 而不是 O(N) 的有序数据结构。
  • 你需要索引做什么?
  • @parktomatomi 容器不需要是连续的,因此可以使用修改后的二叉搜索树来跟踪每个子树中的节点数。这可以轻松更新并用于在遍历期间查找索引。

标签: c++ sorting vector multiset


【解决方案1】:

vector和multiset都不能达到要求。

满足要求的数据结构是平衡二叉搜索树,通过将子树的大小存储在节点中来进行扩充。这种增强的搜索树称为“订单统计树”。

虽然标准库的有序关联容器在内部使用搜索树实现,但标准库不提供可用于实现这一点的通用树数据结构。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 2012-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-18
相关资源
最近更新 更多