【问题标题】:C# efficient datastructure to store objects sorted by key with duplicate keys to fit given requirementsC# 高效的数据结构,用于存储按键排序的对象,并使用重复键来满足给定的要求
【发布时间】:2020-03-20 10:40:52
【问题描述】:

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

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

在排序的数据结构中插入和删除元素的复杂性类不应高于 O(log(N))(在Big O notation 中注明),因为用于排序的属性会经常更改,并且列表必须随每个更新改变以保持一致。

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

选项可能是 C# 模板 SortedSetsSortedDictionariesSortedLists。如果存在重复键,则在从已排序的数据结构中插入或删除时,它们都会失败。

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

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);

从数据结构中插入和删除元素将在 O(log(N)) 中工作,这很好。从 datastructe 中获取所有元素作为列表需要昂贵的Queryable.SelectMany,这会将这个操作的复杂度增加到 O(N^2),这是不可接受的。

当前最好的尝试是使用原语List 并使用BinarySearch 插入和删除来识别插入和删除的索引。对于插入,这给了我最坏情况复杂度 O(log(N))。对于删除平均情况复杂度 O(log(n)),因为重复键很少见,但在最坏情况下为 O(N)(所有对象都具有相同的键)。获取排序列表的所有元素将是 O(1)。

有人能想出一种更好的方法来管理排序数据结构中的对象集合,以满足我的需求,或者目前最好的尝试是一般最好的方法。

感谢您的帮助和有根据的意见。当然,Cookie 是为了获得好的答案。

【问题讨论】:

  • “用于将数据结构中的所有元素按排序顺序作为列表获取的复杂性类不应高于 O(1)。” - 如果那是一个 new 列表,那么我看不出你会比 O(N) 做得更好
  • 当字典中有重复键时,对象必须是列表:SortedDictionary>
  • @Richard Wieditz 你考虑使用C5 库吗?它包含满足您所有要求的TreeBag 集合。顺便说一句,对于原始List,插入和删除元素的复杂性不是 O(log(N))。 O(log(N)) 只是搜索必须插入/删除元素的索引的复杂性。但是插入/删除本身使用Array.Copy 移动元素以插入/删除元素。因此复杂度为 O(M),其中 M
  • Wintellect 的“Power Collections”库中曾经有一组很好的集合,其中包括OrderedMultiDictionary。这曾经在 codeplex 上,但从 been moved to github 开始。可能值得一看。 (它是使用red-black tree 实现的,非常有效。)
  • 感谢@Iliar Turdushev 提供的非常有用的提示!

标签: c# sorting data-structures collections


【解决方案1】:

我认为满足您要求的最简单的解决方案是在比较器中添加平局以确保不会有重复,并在所有对象之间定义总排序。然后你可以使用SortedSet

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

要查找具有特定排名的所有元素,您可以使用SortedSet.GetViewBeteen(),范围为 (rank,min_id) 和 (rank,max_id)。

【讨论】:

    【解决方案2】:

    @Iliar Turdushevs 非常有用的提示:

    您是否考虑使用 C5 库?它包含满足您所有要求的 TreeBag 集合。顺便说一句,对于原始 List,插入和删除元素的复杂性不是 O(log(N))。 O(log(N)) 只是搜索必须插入/删除元素的索引的复杂性。但是插入/删除本身使用 Array.Copy 移动元素以插入/删除元素。因此复杂度为 O(M),其中 M

    【讨论】:

      猜你喜欢
      • 2015-05-21
      • 2017-01-24
      • 1970-01-01
      • 1970-01-01
      • 2019-10-06
      • 2016-11-25
      • 2011-03-18
      • 2013-06-19
      • 1970-01-01
      相关资源
      最近更新 更多