将元素插入到排序数组并找到其索引

时间:2016-02-25 21:17:06

标签: c++ algorithm boost binary-search-tree binary-search

我需要在排序范围内插入一个元素,但我还需要知道它的索引(范围内的元素数量少于元素)。我想在 O(logN)时间内执行此操作。我可以使用基本的C ++容器吗?

我正在考虑使用 std :: multimap ,使用此容器,我可以将元素插入到具有O(logN)复杂度的位置。但是要获取索引,我需要调用std :: distance,它需要进行O(N)操作,因为multimap迭代器不是随机访问。

另一种方法是使用排序的 std :: vector std :: binary_search 算法。在这种情况下,搜索采用O(logN),但插入将采用O(N)操作,因为向量中间的插入是线性操作。

那么,是否有可用于达到结果的std / boost容器,或者我需要为此实现自己的结构?谢谢!

2 个答案:

答案 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容器允许您以多种方式索引容器,但顺序索引和有序索引是独立的。因此,您可以告诉您插入项目的顺序,排序之前/之后的位置,而不是排序中的索引。