从二进制索引树中删除元素

时间:2013-08-01 04:18:39

标签: c++

我有二进制索引树(BIT),它存储了不同的排序值。 例如。 query(1)返回1,query(2)返回2,依此类推。

我想在此BIT中找到第n个最大元素。但是下一次不应该重复这个要素。例如。最初的第4个最大值是4.下一个第4个最大值将是5,之后第4个最大值将是6。

我想到的一种方法是获得第n个最大值,然后从BIT中删除该元素,或者将所有元素右移到该元素1,这样下一次就不会重复。 但是我无法找到如何删除BIT的元素或移位元素。

如果有可能,有人可以告诉你怎么做吗?

1 个答案:

答案 0 :(得分:1)

基本的BIT数据结构如下所示:

value 1|2|3|4|5|6   
f     1|0|2|1|1|3   
c     1|1|3|4|5|8   
tree  1|1|2|4|1|4

其中:

  

f [i] - 索引为i的值的频率,i = 1 .. MaxVal
   c [i] - 指数i的累积频率(f [1] + f [2] + ... + f [i])
   tree [i] - 以索引i

存储在BIT中的频率之和

(以上内容直接来自此article)。

查看上面的数据结构,我们可以看到在O(log n)时间内无法进行删除。想象一下,我们想要从树中删除第一个元素。为了做到这一点,我们需要更新f [0],c [0]和tree [0],以反映树中不再存在该元素。不幸的是,我们还需要迭代c结构的其余部分,因为它代表累积和。将c [0]设置为0后,c [1]不再准确,必须更新,c [2]不再准确......直到c [n-1]。

在最坏的情况下,这将是O(n)操作,最坏的情况是删除树中的第一个元素。

我认为使用不同的数据结构将是一个更明智的选择。 BIT和其他二叉树非常适合有效地查找和添加元素,但不如删除元素。我建议使用优先级队列。优先级队列(参见this维基百科文章),通常使用最小堆作为其基础数据结构,并保证删除O(log n)。