是否存在具有高效插入/删除的数据结构,但具有位置排序?

时间:2013-05-30 15:44:25

标签: javascript .net data-structures

我正在寻找一个具有高效插入,删除和查找的数据结构,二进制树通常符合这些数据结构,但是我的项目不是根据它们的值进行排序 - 而是我需要根据它们的实际情况对它们进行排序插入位置(即像数组一样)。所有操作都将根据此位置访问,插入或删除项目,就像使用数组一样。

  • getItem(int position)
  • addItem(int insertPosition,object item)
  • removeItem(int position)

所以基本上问题是插入/删除项会导致其后面的所有项目的索引都移动了1.显然存储索引永远不会比O(n)更好,所以基本的二进制树/哈希表都没有了

是否有能够在线性时间内实现所有这些操作的结构?我一直认为二进制树可以以某种方式进行调整,并且我支持通过索引查找,让每个节点存储其左侧分支中的节点数。

2 个答案:

答案 0 :(得分:0)

用指数注释的2-3个手指树应该能够做到这一点。它们是持久的(在函数编程意义上),可能是好的也可能是坏的。如果你想要一个可变的变体,它至少是一个想法的来源。 2-3手指树支持

  1. 对数时间访问,
  2. 在分摊的常数时间内以开头和结尾添加和删除,
  3. 按时间分割和连接小块的大小。
  4. 因此要在任意位置插入,可以在该位置拆分,添加到其中一个零件的末尾,然后连接。 同样,要删除项目,您可以拆分该索引,删除该项目,然后再次连接。两者都花费少于O(log n)时间,这是一个过度近似。

    现有的实现(特殊的索引注释,并针对性能进行了调整)是Haskell中的Data.Sequence模块。引入它们的paper比它需要的更难阅读。有一个article更清楚地解释了一般的想法,但省略了许多细节,因此实施它们是不够的。

答案 1 :(得分:-1)

List支持这些功能,如果容量>则为O(1)添加。数

List.Add Method

其他一切都是O(N),但在实践中更好 如果你在0位置插入那么它是O(N)但如果你在倒数第二个位置插入,你会发现它比O(N)更好。

    List<simple> ls = new List<simple>();
    simple ss = new simple(0);
    ls.Add(ss);
    ls.Add(new simple(2));
    ls.Insert(0, new simple(1));
    ls.Add(new simple(3));
    ls.Add(new simple(4));
    ls.RemoveAt(2);
    foreach(simple s in ls) 
    {
        System.Diagnostics.Debug.WriteLine(s.ID);
    }
    System.Diagnostics.Debug.WriteLine(ls[1].ID.ToString());
    System.Diagnostics.Debug.WriteLine(ls.IndexOf(ss).ToString());
}
public class simple
{
    public Int32 ID { get; private set; }
    public simple(Int32 id) { ID = id; }
}