插入的高效数据结构

时间:2012-04-06 12:33:15

标签: c++ list data-structures insertion

我正在寻找一种数据结构(类似数组),允许快速(比O(N)更快)任意插入值到结构中。数据结构必须能够以插入方式打印出元素。这类似于List.Insert()(它太慢了,因为它必须移动每个元素),除了我不需要随机访问或删除。插入将始终在'数组'的大小范围内。所有值都是唯一的。不需要其他操作。

例如,如果Insert(x,i)在索引i(0-indexing)处插入值x。然后:

  • 插入(1,0)给出{1}
  • 插入(3,1)给出{1,3}
  • 插入(2,1)给出{1,2,3}
  • 插入(5,0)给出{5,1,2,3}

它最终需要能够打印出{5,1,2,3}。

我正在使用C ++。

6 个答案:

答案 0 :(得分:9)

使用skip list。另一种选择应该是tiered vector。跳过列表在const O(log(n))执行插入并按顺序保存数字。分层向量支持插入O(sqrt(n))并再次按顺序打印元素。

编辑:根据amit的评论,我将解释如何在跳过列表中找到第k个元素:

对于每个元素,您在下一个元素的链接上都有一个塔,并且对于每个链接,您知道它跳过了多少个元素。因此,寻找第k个元素,从列表的头部开始,然后沿着塔向下走,直到找到跳过不超过k个元素的链接。您转到此节点指向的节点,并使用跳过的元素数减少k。继续这样做,直到你有k = 0。

答案 1 :(得分:1)

您考虑使用std::map还是std::vector

您可以使用插入等级的std::map作为关键字。 vector有一个reserve成员函数。

答案 2 :(得分:1)

您可以使用std::map映射(索引,插入时间)对值,其中inserted-time是“自动增量”整数(以SQL术语表示)。对的排序应该是

(i, t) < (i*, t*)

当且仅当

i < i* or t > t*

在代码中:

struct lt {
    bool operator()(std::pair<size_t, size_t> const &x,
                    std::pair<size_t, size_t> const &y)
    {
        return x.first < y.first || x.second > y.second;
    }
};

typedef std::map<std::pair<size_t, size_t>, int, lt> array_like;

void insert(array_like &a, int value, size_t i)
{
    a[std::make_pair(i, a.size())] = value;
}

答案 3 :(得分:1)

关于你的评论:

  

List.Insert()(它太慢了,因为它必须移动每个元素),

列表不会移动它们的值,它们会迭代它们以找到您要插入的位置,请小心您的说法。这对像我这样的新手来说可能会让人感到困惑。

答案 4 :(得分:0)

默认情况下,GCC附带的解决方案是 rope 数据结构。这是documentation。通常,在处理长字符串时会想到绳索。这里我们有int而不是字符,但它的工作方式相同。只需使用int作为模板参数即可。 (也可能是pair s等)

这是description of rope on Wikipedia

基本上,它是一个二叉树,用于维护左右子树中有多少元素(或等效信息,即所谓的顺序统计),这些计数会相应更新为插入和删除元素时,子树会旋转。这允许O(lg n)操作。

答案 5 :(得分:-1)

在c ++中你可以使用矢量图,如下所示:

int main() {
  map<int, vector<int> > data;
  data[0].push_back(1);
  data[1].push_back(3);
  data[1].push_back(2);
  data[0].push_back(5);
  map<int, vector<int> >::iterator it;
  for (it = data.begin(); it != data.end(); it++) {
    vector<int> v = it->second;
    for (int i = v.size() - 1; i >= 0; i--) {
      cout << v[i] << ' ';
    }
  }
  cout << '\n';
}

打印:

5 1 2 3 

就像你想要的那样,插入是O(log n)。