快速插入/删除的数组

时间:2017-02-26 13:31:39

标签: data-structures linked-list

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

  1. 访问给定索引处的元素
  2. 在给定索引处添加或删除元素(从而移动以下元素)
  3. Arrays在O(1)中执行第一个操作,但第二个操作采用O(n),而链接列表执行相反的操作。是否存在中间数据结构?比方说,可以在O(lg n)或O(n ^ epsilon)“最坏情况”时间内进行两种操作?

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

3 个答案:

答案 0 :(得分:2)

AVL-Array'是一个STL风格的容器 在 O(log n)

中执行这两项操作

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

请注意,AVL-Array未实现搜索树, 而是一个顺序的容器 碰巧是树形的。索引,迭代,插入 并删除所有你做的事情 期待vector做。

你可以找到它here

答案 1 :(得分:1)

您可以使用一种平衡二叉树来执行此操作,其按顺序遍历按顺序给出数组元素,即最左边的节点存储A[0],最右边的节点存储A[n-1],其中{ {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)中迭代一长度k的序列,并在O(k)中向前或向后跳过A[i]A[i+k]A[i-k]

答案 2 :(得分:0)

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