我正在寻找一个存储元素数组并支持这些操作的数据结构:
Arrays在O(1)中执行第一个操作,但第二个操作采用O(n),而链接列表执行相反的操作。是否存在中间数据结构?比方说,可以在O(lg n)或O(n ^ epsilon)“最坏情况”时间内进行两种操作?
请注意,我不是要求平衡的二叉搜索树。每次添加/删除新元素时,键(索引)都会被更改和移位。例如,删除最小元素会将所有其他元素的索引减少1。
答案 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