我在书中找到了这个:
Design a data structure for maintaining dynamic sequence x_1, x_2,... , x_n
which provides operations:
Insert(a,i) - inserts a as x_i, indexes from i+1 to n go up by 1
Delete(i) - deletes x_i, indexes from i+1 to n go down by 1
Find(i) - returns element x_i
Sum_even() - returns sum of the elements with even indexes
序列是动态的,所以我想使用AVL树来保存它。所以我认为我可以使用标准技巧进行查找,删除和插入 - 只需保留以此节点为根的子树的每个节点大小。然后我可以轻松地导航树以在O(log n)时间内找到第i个元素。然后给我:x_1,x_2,...,x_n。
但是对于Sum_even(),我可能还应该在每个节点中使用偶数和奇数索引的元素之和。虽然插入或删除时很难更新。如何运作,任何人都可以帮忙吗?
答案 0 :(得分:2)
您不必在节点中存储子树的大小。 AVL树仅存储左右子树高度的差异:-1,0或+1。
为了轻松维护sum_even
,您需要为每个节点存储sum_even
和sum_odd
。它将是子树的偶数/奇数索引的值的总和。
因此每个节点都有变量:
difference
左右子树的高度差异value
parity
子树大小的奇偶校验(0或1)sum_even
sum_odd
对于插入和删除,请使用标准算法http://en.wikipedia.org/wiki/AVL_tree。 但是对于每个受影响的节点(直到根节点和旋转节点的节点)更新值:
parity := (left.parity + right.parity + 1) % 2
if left.parity == 0
sum_even := left.sum_even + right.sum_odd
sum_odd := left.sum_odd + right.sum_even + value
else
sum_even := left.sum_even + right.sum_even + value
sum_odd := left.sum_odd + right.sum_odd