什么是具有快速插入+删除和部分反转的良好数据结构?

时间:2014-03-17 04:12:44

标签: c++ c++11 data-structures linked-list bitwise-xor

我正在用C ++编写一个算法,为此我需要一个数据结构来存储一系列n个数据点。也就是说,我想存储元素v[0],v[1],...,v[n-1]。我确实关心订单。

我希望快速开展的行动是:

  1. 顺序访问(即访问v[0],然后访问v[1]等等,并具有编辑值的功能);
  2. 点重定位,即

    {v[0],v[1],...,v[i],v[i+1],...,v[j-1],v[j],v[j+1],...,v[n-1]} - > {v[0],v[1],...,v[i],v[j],v[i+1],...,v[j-1],v[j+1],...,v[n-1]};

  3. 部分回归,即

    {v[0],...,v[i],v[i+1],...,v[j-1],v[j],v[j+1],...,v[n-1]} - > {v[0],...,v[i],v[j],v[j-1],...,v[i+1],v[j+1],...,v[n-1]}

  4. 似乎我可以使用XOR-linked list来实现我的算法,它会给出最小的复杂度(上面的操作将为O(1),为我的算法提供O(n^2)。但我知道,XOR链表被认为是一个丑陋的数据结构" ([1][2])。

    这对于什么是好的数据结构呢?更确切地说,还有其他常用的数据结构,在O(1)时间内实现这些操作吗?

2 个答案:

答案 0 :(得分:1)

这取决于你没有提到的更多因素。

首先,它取决于元素的大小及其复制代码。如果你有小元素(大约64字节或更少)并且他们的复制(或移动)是便宜的(甚至是微不足道的(在POD类型意义上)),那么使用std::vector可能是一个非常很好的选择,即使是“更糟糕”的时间复杂性(顺便说一句,作为未来的小窍门,不要过于追求最小的时间复杂性,它只是整个故事的一部分)。

如果您的元素琐事,尤其如此,因为向量中的旋转操作将非常快(尽管仍为O(n)),而其他操作在与链表相比的时间复杂度。

其次,这取决于您执行上述不同操作的频率。通过链表进行顺序访问实际上效率很低,如果经常进行遍历,通常不建议使用它们。

如果您的元素太小而您考虑使用XOR链接列表(为每个元素节省一个指针),那么您可能根本不应该使用链接列表。说实话,我不确定XOR链接列表是否真的值得(但我不想进入)。

总的来说,我不得不说你应该测试这三个选项:linked-list(std::forward_liststd::list),std::vector或者指针向量(例如std::vector< std::unique_ptr<T> >)。另一个选择可能是unrolled linked-list,但这只会在我提到的因素的特定制度中有用。

我重申,我说测试他们,因为这是你知道什么是最好的唯一方法。 “分析”仅用于经验法则,不再是我最喜欢的引用之一:

  

就数学定律而言,它们指的是现实,它们并不确定;只要他们确定,他们就不会提到现实。 (阿尔伯特爱因斯坦)

答案 1 :(得分:0)

我只会使用std::vector<T>,如果您发现在实践中操作过于昂贵,那么只会寻找可能更有效的数据结构。

  1. std::vector<T>的顺序访问非常有效。
  2. std::rotate algorithm适用于操作2.
  3. std::reverse algorithm适用于操作3。
  4. 上述算法位于<algorithm> header