【问题标题】:How to find the index of an element in sorted set?如何在排序集中找到元素的索引?
【发布时间】:2011-05-09 10:46:57
【问题描述】:
我可以在O(logN) 的有序集合(由 BST 支持)中找到一个元素。现在我想要这个元素的 index。例如,在集合{1, 3, 4, 10}中,4的索引为2,1的索引为0。
显然,我可以迭代集合,所以简单的解决方案是O(N)。我们可以使用可能的 BST 属性和/或辅助数据结构做得更好吗?
【问题讨论】:
标签:
search
data-structures
binary-search-tree
sortedset
【解决方案1】:
使用简单的 BST,其中元素的插入顺序是随机的,您可以确定有多少元素小于给定元素,而无需遍历树。
如果您有一棵平衡树,例如红黑树,那么您至少可以根据树的高度限制在索引上设置下限和上限。
如果将元素插入 BST 的顺序是非随机的,那么您可以在不遍历树的情况下说出树的高度并给出近似索引的估计值。
至于辅助数据结构,您可以创建一个辅助字典,将元素映射到它们的索引。但是,构建该索引需要 O(N) 时间,并且当您向 BST 添加新元素时,索引会变得陈旧,因此这只适用于不经常更新的 BST。
另一种解决方案是使用两个属性扩展 BST 节点:索引和计数。索引表示树中有多少小于此节点中的元素。该计数表示您上次更新该节点的索引时 BST 中有多少元素。在 BST 上对插入、删除和搜索进行比较简单的更改,不会影响超出常数时间的那些基本操作,并且可以在 O(1) 内直接获取元素的索引。
本质上,当您插入一个新节点时,对于您向下传递的每个节点,如果新元素较小(即您的下一步是左子节点),则增加该节点的索引和计数。当你找到新元素的位置时,你根据它的父元素给它一个计数,并根据它的父元素和左子元素给它一个索引。
这会使元素大于新的元素并具有错误的索引,但是您可以在搜索元素时通过引用父元素的计数值轻松更新它 - 父元素和子元素的计数之间的差异告诉您如何自您上次更新子索引以来,发生了许多较小元素的插入,因此您只需将差异添加到索引中即可。