如何在O1或Olog n时间中获得集合中键最小的元素?

问题描述

| 我知道我可以使用
Dictionary
并在O(1)时间中检索任意元素。 我知道我可以在O(1)时间的ѭ1中获得下一个最高(或最低)的元素。但是,如果我想删除
SortedDictionary
中的第一个值(基于
TKey
\'s
IComparable
)怎么办? 我可以使用
.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)),则需要一个排序的数据结构,以便可以根据值的位置推断值的相对位置。