增加AVL树,序列

时间:2012-12-14 18:16:44

标签: algorithm data-structures

我在书中找到了这个:

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(),我可能还应该在每个节点中使用偶数和奇数索引的元素之和。虽然插入或删除时很难更新。如何运作,任何人都可以帮忙吗?

1 个答案:

答案 0 :(得分:2)

您不必在节点中存储子树的大小。 AVL树仅存储左右子树高度的差异:-1,0或+1。

为了轻松维护sum_even,您需要为每个节点存储sum_evensum_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