问题描述
|
我知道我可以使用
Dictionary
并在O(1)时间中检索任意元素。
我知道我可以在O(1)时间的ѭ1中获得下一个最高(或最低)的元素。但是,如果我想删除SortedDictionary
中的第一个值(基于TKey
\'sIComparable
)怎么办?
我可以使用.First()
方法检索最小的密钥吗?它的复杂性是什么?它会在O(1),O(log n)或O(n)的时间运行吗?
ѭ1正确的数据结构吗?
注意:用例是穷人的优先队列或有序队列。不允许使用开放源代码(必须是从头开始的代码,或者已经在.NET 3.5框架中)。
解决方法
SortedList和SortedDictionary在内部以二进制搜索树的形式实现,理想情况下可以为Min提供O(log n)性能(需要遍历树,但不枚举整个列表)。但是,使用LINQ执行该Min可能会枚举整个列表。
我认为跳过列表是一种更好的替代数据结构。
,SortedDictionary.GetEnumerator被声明为具有O(log n)时间-因此First()应该紧随其后。
,如果您有
SortedDictionary
或SortedList
,则可以使用.First()
(或dict.Keys[0]
表示SortedList
),否则,您可以执行以下操作:
dict[dict.Keys.Min()]
这将花费O(N)的总时间(因为Min()必须迭代整个集合)
.First()
对于SortedList可能有O(1)的时间,对于SortedDictionary有O(log n)的时间。
对于SortedDictionary,插入和删除时间为O(log N),对于SortedList,插入和删除时间最多为O(N)。请注意,如果您使用词典来支持“优先级队列”,则不能有两个优先级相同的项目。
我认为这两个类都不具有Last的特殊实现,因此,如果您想要最高价值的钥匙,则应该使用SortedList,因为您可以做dict.Keys[dict.Count-1]
。如果只希望最高(而不是最低),则可以使用比较器按该顺序排序,然后使用“第一”。
,由于您只提到获取值而不设置值,
您可以使用一个简单的列表,对其进行预先排序,然后按顺序访问O(1)中的任何值。
,为什么不保留键的单独排序列表,以便仅通过执行dict[keyList[0]]
就可以始终获取具有最小键的元素。
,对于未排序的集合,获得最高或最低元素是O(n),因为任何一项都可能是最高或最低,因此您必须查看每一项。如果要快速执行此操作(O(1)),则需要一个排序的数据结构,以便可以根据值的位置推断值的相对位置。