【问题标题】:Array with fast insertion/deletion快速插入/删除的数组
【发布时间】:2017-07-17 02:02:46
【问题描述】:

我正在寻找一种存储元素数组并支持这些操作的数据结构:

  1. 访问给定索引处的元素
  2. 在给定索引处添加或删除元素(并因此移动以下元素)

数组在 O(1) 中执行第一个操作,但第二个操作需要 O(n),而链表则相反。是否存在中间数据结构?比如说,可以在 O(lg n) 或 O(n^epsilon) “最坏情况”时间内完成这两种操作的东西?

请注意,我不是要求平衡二叉搜索树。每次添加/删除新元素时,键(索引)都会更改和移动。例如,删除最小元素会将所有其他元素的索引减少 1。

【问题讨论】:

  • 这个公式是不精确的。每个平衡的搜索树都将在 log n 时间内支持两者。如果您将键视为索引,则完成。 (但它不是影响您的任务中未考虑的迭代的元素数组;这就是您的问题开始不精确的地方)
  • @sascha 关键是元素没有顺序。唯一的顺序是通过添加或删除它们隐式创建的顺序。我会让它更精确。
  • 还是太宽泛了。这是一个非常模糊的规范,很难使用。您仍然可以使平衡的搜索树工作。它不会更改以下索引的索引,但这并不重要,因为您的访问/迭代仍然表现得好像这会发生一样。您只需要使用一些不断增长的索引作为每个插入的键,并且可能保留一个键间隙计数器。 (你有朋友支持你的 cmets 吗?:-D)
  • 一根绳子在叶子上用单个元素代替绳子就可以了
  • @harold 绳索中的重新平衡可能需要线性时间。 sgi.com/tech/stl/ropeimpl.html 再平衡的最坏情况成本在字符串中仍然是线性的。但是,观察到的行为是重新平衡通常会消耗一小部分运行时间。事实上,所有通过重复连接构建长度为 N 的绳索的自然方法都需要在 N 中线性的总时间。设计违反这一点的连接序列是可能的,但并不简单。

标签: data-structures linked-list


【解决方案1】:

有“AVL-Array”,一个 STL 风格的容器, 在 O(log n) 中执行这两个操作。

它是建立在 AVL-Tree 之上的,但它仍然不是 一个关联容器,但顺序。
它支持索引访问[]vector 语义。

注意 AVL-Array 没有实现 搜索 树, 而是一个顺序容器,
碰巧以树的形式出现。索引、迭代、插入 和删除都做你想做的事
期待vector 这样做。

你可以找到它here

【讨论】:

    【解决方案2】:

    你可以用一种平衡二叉树来做到这一点,它的中序遍历给出了数组元素的顺序,即最左边的节点存储A[0],最右边的节点存储A[n-1],其中n是数组中的元素数。

    在每个节点,我们将存储以该节点为根的子树的总大小s(即节点总数),存储在该节点的数组元素的值v,左孩子节点的l,以及节点的右孩子r

    您可以从这样的树中检索A[i] 的值,如下所示(为说明简单,不检查错误条件):

    int get_element(node *n, int i) {
      int ls = (n->l == NULL) ? 0 : (n->l)->s;
    
      if (i < ls) return get_element(n->l, i);
      else if (i == s) return n->v;
      else return get_element(n->r, i-(ls+1));
    }
    

    如果树是平衡的,这将花费O(log n) 时间。在索引处插入或在索引处删除类似于任何平衡树方案,不同之处在于您使用子树大小而不是键值来导航,这也将采用O(log n)。平衡树数据结构通常使用“旋转”来恢复平衡,例如,右旋转:

       y o                  o x  
        / \                / \   
     x o   C     ==>      A   o y
      / \                    / \ 
     A   B                  B   C
    

    我们可以将节点y的新子树的大小保持为size(B)+size(C)+1,然后将x的大小保持为size(A)+size(y)+1

    如果您使用手指搜索树中的想法,那么您还可以在O(n) 中遍历整个数组,在O(k) 中遍历长度为k 的序列,并从A[i]A[i+k]A[i-k]O(log k)

    【讨论】:

      【解决方案3】:

      B-tree 是一个不错的选择。 https://en.wikipedia.org/wiki/B-tree

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-09
        • 1970-01-01
        • 2011-07-09
        • 1970-01-01
        • 1970-01-01
        • 2018-06-02
        • 1970-01-01
        • 2021-06-06
        相关资源
        最近更新 更多