寻找具有多个键的可索引的自排序数据结构

时间:2015-04-20 12:22:28

标签: java sorting data-structures

我想存储<Integer, Object>对,并用整数键按升序保存它们。但是,应该允许它为结构中的不同对象保留相同的键,这样我就不能使用其中一个标准映射。

此外,这些对应该能够通过索引来处理。因此,如果我想在索引2处寻址对(第三大整数值),它应该返回存储在那里的对象。之后我想更改整数值,再次对结构进行排序,并根据升序重新排列索引。

此结构中的对数将保持不变,因此我不需要有效插入或删除,只需高效排序。

Java中是否存在这样的数据结构(或至少在一般情况下)?

2 个答案:

答案 0 :(得分:0)

如果您要为多个条目使用相同的密钥,则应考虑使用Google Guava中的MultiMap

http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Multimap.html

MultiMap接口的一个实现是SortedSetMultimap,在您的情况下非常有用。

答案 1 :(得分:0)

这可能有点过于具体而无法存在于通用库中,但可用于有效解决此问题的数据结构是order statistic tree(即自平衡二叉搜索树(BST) )其中每个节点存储以该节点为根的子树的大小。)

插入和删除此树(我们可以将更新定义为删除后跟插入)看起来与常规BST完全相同,除了适当增加和减少子树大小。

要获取第i个元素,我们从根开始,并通过查看节点数重复确定目标节点将在哪个子子树中。

上述任何操作都需要O(log n)时间。

如果您能够以某种方式使用相同整数值的order元素(例如使用相应的对象),则上述内容将按原样运行。如果它们不能被排序,那么也可以让每个节点成为具有相同整数值的元素的集合(例如List),然后,我们跟踪节点,而不是节点的数量。每个子树中的元素数量(即每个节点的大小总和)。

注意:如果找不到库或自平衡实现,最简单的方法是采用红黑树的工作实现并修改它以跟踪大小。

如果您更喜欢简单:

如果您对O(n)感到满意以获得第i个元素和每个更新的O(log n),您可以像我上面描述的那样使用TreeMap<Integer, List<Object>> (或Guava's MultiMap),即让每个节点存储具有该整数值的对象列表。然后,要找到第i个元素,您可以简单地遍历并跟踪我们到目前为止遇到的元素数量。

如果您对O(1)获得第i个元素感到满意,但是每次更新都是O(n),您可以简单地使用已排序的ArrayList并迭代查找正确的元素并将其转移到正确的位置。可以优化更新以使用二进制搜索,但它仍然是O(n)。