C ++:用于有效插入和检索自定义数据的数据结构

时间:2012-04-18 03:16:46

标签: c++ data-structures vector set sorted

我遇到过C ++(在Windows上)的情况,我需要保留一对int:对,其中 start 值是唯一的(我们不需要关心这一点)。 所需的操作是:

  • 插入对
  • 检索对X:这应该返回Y开始的对Y< X的开始< X的结束< Y结束了。如果Y不存在,则返回false。

基本解决方案是简单地保留一组对。为了检索,我们将按顺序遍历集合进行检查。这是O(n)。

我正在寻找更好的解决方案。我目前看到2个候选数据结构:

  1. 排序矢量
  2. STL的集合(内部实现为二叉搜索树?)
  3. 排序矢量: 优点:可以自定义二进制搜索以支持检索操作。这是O(logn) 缺点:如何有效地插入新对以维护排序顺序。如何避免重新分类O(nlogn)的成本?

    组: 优点:使用标准插入方法轻松插入。这是O(1)? 缺点:如何避免顺序搜索?如何做得比O(n)好?

    感谢您的建议。

    我也对任何其他可以有效的结构开放(第一个标准是速度;第二个是内存)支持上面提到的2个操作。

1 个答案:

答案 0 :(得分:1)

目前尚不清楚范围是否可以重叠,但如果不能,那么这应该有效。我已经包含了一个完整的测试示例。

#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <map>

struct RangeContainer {
  typedef std::map<int,int> RangeMap;
  typedef std::pair<int,int> Range;

  void insert(const Range &range)
  {
    range_map.insert(range);
  }

  Range find(const Range &x) const
  {
    RangeMap::const_iterator iter = range_map.upper_bound(x.second);
    if (iter==range_map.begin()) {
      return invalidRange();
    }
    --iter;
    Range y = *iter;
    if (y.first<x.first && x.second<y.second) {
      return y;
    }

    return invalidRange();
  }

  static Range invalidRange()
  {
    return Range(INT_MAX,INT_MIN);
  }

  RangeMap range_map;
};


static void test1()
{
  RangeContainer c;
  typedef RangeContainer::Range Range;
  c.insert(Range(1,10));
  c.insert(Range(20,30));
  assert(c.find(Range(-5,-4))==c.invalidRange());
  assert(c.find(Range(1,10))==c.invalidRange());
  assert(c.find(Range(2,9))==Range(1,10));
  assert(c.find(Range(2,10))==c.invalidRange());
  assert(c.find(Range(11,19))==c.invalidRange());
  assert(c.find(Range(21,29))==Range(20,30));
  assert(c.find(Range(20,29))==c.invalidRange());
  assert(c.find(Range(21,30))==c.invalidRange());
  assert(c.find(Range(35,40))==c.invalidRange());
}

int main(int argc,char **argv)
{
  test1();
  return EXIT_SUCCESS;
}