我需要在排序范围内插入一个元素,但我还需要知道它的索引(范围内的元素数量少于元素)。我想在 O(logN)时间内执行此操作。我可以使用基本的C ++容器吗?
我正在考虑使用 std :: multimap ,使用此容器,我可以将元素插入到具有O(logN)复杂度的位置。但是要获取索引,我需要调用std :: distance,它需要进行O(N)操作,因为multimap迭代器不是随机访问。
另一种方法是使用排序的 std :: vector 和 std :: binary_search 算法。在这种情况下,搜索采用O(logN),但插入将采用O(N)操作,因为向量中间的插入是线性操作。
那么,是否有可用于达到结果的std / boost容器,或者我需要为此实现自己的结构?谢谢!
答案 0 :(得分:3)
您可以使用Boost.MultiIndex' ranked indices:
<强> Live Coliru Demo 强>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ranked_index.hpp>
#include <boost/multi_index/identity.hpp>
using namespace boost::multi_index;
using ranked_int_set=multi_index_container<
int,
indexed_by<
ranked_unique<identity<int>>
>
>;
#include <iostream>
int main()
{
ranked_int_set s={0,2,4,6,8,10,12,14,16};
auto it=s.insert(9).first;
std::cout<<"9 was inserted at position #"<<s.rank(it)<<"\n";
std::cout<<"14 is located at position #"<<s.find_rank(14)<<"\n";
}
输出
9 was inserted at position #5 14 is located at position #8
答案 1 :(得分:2)
没有。我找了它。
有一种方法可以实现这一点。从二叉树或跳过列表开始,并保持子树/跳过的大小(一些额外的开销 - 当插入项目时,您必须回溯到父项/跳过并递增,并且类似于删除)。 / p>
然后你可以在lg n时间内获得索引,随机访问(通过索引或偏移量),并保持同时排序。
我试图找到一个预先写好的容器来做这件事是徒劳的,而且这个项目是罐装的,所以我没有开始编写它。
可以使用一个完整的数据库,对已排序的列进行索引,您可能能够快速地获得该数字。
如果简单的线性排序向量不合理(使用昂贵的插入式中间符号),则可能无论如何都要考虑数据库。
作为看起来很有希望但失败的容器的示例,Boost的MultiIndex容器允许您以多种方式索引容器,但顺序索引和有序索引是独立的。因此,您可以告诉您插入项目的顺序,排序之前/之后的位置,而不是排序中的索引。