如何在排序集中找到元素的索引?

时间:2011-05-09 10:46:58

标签: search data-structures binary-search-tree sortedset

我可以在O(logN)中找到排序集(由BST支持)中的元素。现在我想要这个元素的索引。例如,在集合{1, 3, 4, 10}中,4的索引为2,而1的索引为0

显然,我可以迭代集合,所以简单的解决方案是O(N)。我们可以使用可能的BST属性和/或辅助数据结构做得更好吗?

1 个答案:

答案 0 :(得分:3)

使用简单的BST(随机元素的插入顺序),您可以确定在没有遍历树的情况下,有多少元素确切地小于给定元素。

如果你有一个平衡的树,比如红黑树,那么你至少可以在索引上设置一个下限和上限,因为树的高度是界限。 如果元素插入BST的顺序是非随机的,那么你可以再说一下树高,而不是走它,并给出一些近似指数的估计。

对于辅助数据结构,您可以创建一个辅助字典,将元素映射到其索引。但是,构建该索引需要O(N),并且当您向BST添加新元素时索引会变得陈旧,因此这仅适用于不经常更新的BST。

另一个解决方案是使用两个属性扩展BST节点:index和count。索引表示在树中有多少小于此节点中的元素。计数表示当您上次更新该节点的索引时,BST中有多少元素。通过对BST的插入,删除和搜索进行相对简单的更改,不会影响超出常量时间的基本操作,并且可以直接在O(1)中获取元素的索引。

基本上,当您插入一个新节点时,对于您向下传递路径的每个节点,如果新元素较小(即您的下一步是左子节点),则递增该节点的索引和计数。当您找到新元素的位置时,您可以根据其父元素给它一个计数,并根据其父元素和左子元素给出一个指数。 这使得元素大于具有错误索引的新元素,但是当您通过引用父级的计数值搜索元素时,您可以轻松地更新元素 - 父级和子级的计数之间的差异告诉您如何自上次更新子索引以来,发生了许多较小元素的插入,因此您只需将该差异添加到索引中即可。