C#高效的数据结构,用于存储按键排序的对象,具有重复键以满足给定要求

C#高效的数据结构,用于存储按键排序的对象,具有重复键以满足给定要求,c#,sorting,data-structures,collections,C#,Sorting,Data Structures,Collections,我正在寻找一种最有效的方法,在编程语言C#中使用object属性存储由Comparator排序的对象集合 存在属性值相同的对象,因此集合中会出现重复的键 用于在排序数据结构中插入和删除元素的复杂度类不应高于O(log(N))(如中所述),因为用于排序的属性将经常更改,并且列表必须随着每次更改而更新,以保持一致 以排序顺序获取数据结构中的所有元素作为列表的复杂类不应高于O(1) 选项可能是C#模板,或者。如果存在重复键,则在从排序数据结构中插入或删除时,所有这些操作都会失败 一种解决方法可能是使用

我正在寻找一种最有效的方法,在编程语言C#中使用object属性存储由Comparator排序的对象集合

存在属性值相同的对象,因此集合中会出现重复的键

用于在排序数据结构中插入和删除元素的复杂度类不应高于O(log(N))(如中所述),因为用于排序的属性将经常更改,并且列表必须随着每次更改而更新,以保持一致


以排序顺序获取数据结构中的所有元素作为列表的复杂类不应高于O(1)

选项可能是C#模板,或者。如果存在重复键,则在从排序数据结构中插入或删除时,所有这些操作都会失败

一种解决方法可能是使用如下所示的堆叠SortedDictionary,将具有相等键的对象聚合为单独的集合,并按另一个唯一键(例如ID)对其进行排序:

SortedDictionary sPresortedByRank=
新的SortedDictionary(新的ByRankasSortedDictionary());
长秩=52
sPresortedByRank[rank]=新的分类字典(新的BYIDASCSORTEDDDICTIONARY);
从数据结构中插入和删除元素将在O(log(N))中工作,这是很好的。从datastructe获取所有元素作为列表需要一个昂贵的过程,这会将此操作的复杂性增加到O(N^2),这是不可接受的

当前的最佳尝试是使用原语和insert和delete来标识插入和删除的索引。对于insert,这给了我最坏的情况复杂性O(log(N))。对于删除,平均大小写复杂度O(log(n)),因为它很少会重复密钥,但在最坏的情况下O(n)(具有相同密钥的所有对象)。获取已排序列表的所有元素将是O(1)

有人能想象出一种更好的方法来管理排序数据结构中的对象集合,这种方法适合我的需要吗?或者说,当前的最佳尝试通常是最好的


感谢您的帮助和有根据的意见。当然,Cookies是很好的答案。

我认为满足您要求的最简单的解决方案是在比较器中添加断开连接,以确保没有重复项,并在所有对象之间定义总顺序。然后您可以只使用
SortedSet

例如,如果您可以在每个对象中都有一个ID,那么您可以按(rank,ID)排序,而不是按“rank”排序,从而使比较器成为一个总排序


要查找具有特定等级的所有元素,您可以使用范围为(等级,最小id)和(等级,最大id)的
SortedSet.GetViewBeteen()

@Iliar Turdushevs非常有用的提示:


<>你考虑使用C5库吗?它包含满足所有需求的树状图集合。顺便说一下,对于基元列表,插入和删除元素的复杂性不是O(log(N))。O(log(N))是搜索必须插入/删除元素的索引的唯一复杂性。但是插入/删除本身使用Array.Copy来移动元素以插入/删除元素。因此,复杂性将是O(M),其中M“以排序顺序获取数据结构中所有元素作为列表的复杂性类不应高于O(1)。”-如果这是一个新列表,那么我看不出您将如何比O(N)做得更好当字典中存在重复键时,对象必须是列表:SortedDictionary@RichardWieditz,你考虑使用图书馆吗?它包含满足您所有需求的
TreeBag
集合。顺便说一下,对于primitive
List
来说,插入和删除元素的复杂性不是O(log(N))。O(log(N))是搜索必须插入/删除元素的索引的唯一复杂性。但是插入/删除本身使用
Array.Copy
移动元素以插入/删除元素。因此,复杂性将是O(M),其中M在Wintellect的“Power collections”库中曾经有一组很好的集合,其中包括。这以前是在codeplex上,但现在是。也许值得一看。(它是用一个非常有效的方法实现的。)感谢@Iliar Turdushev提供了这个非常有用的提示!
SortedDictionary<long, SortedDictionary<long, RankedObject>> sPresortedByRank = 
new SortedDictionary<long, SortedDictionary<long, RankedObject>>(new ByRankAscSortedDictionary());

long rank = 52
sPresortedByRank[rank] = new SortedDictionary<long, RankedObject>(new ByIdAscSortedDictionary);