我正在尝试做一些非常简单的事情,但似乎我不理解SortedDictionary
。
我要做的是以下几点:
创建一个排序字典,按照某个浮点数对我的项目进行排序,因此我创建了一个类似于此字典的字典
SortedDictionary<float, Node<T>> allNodes = new SortedDictionary<float, Node<T>>();
现在我添加项目后,我想逐个删除它们(每次删除都应该从最小到最大的复杂度为O(log(n))。
我该怎么办?我认为只是allNodes[0]
会给我最小的,但事实并非如此。
此外,似乎字典无法处理重复键。我觉得我使用的是错误的数据结构...... 如果我有一堆节点要按其距离(浮点)排序,我应该使用其他东西吗?
答案 0 :(得分:15)
allNodes[0]
不会向您提供字典中的第一项 - 它会为您提供float
键值 0
的商品。
如果您想要第一项,请尝试allNodes.Values.First()
。或者找到第一个键使用allNodes.Keys.First()
逐个删除项目,循环遍历Keys
集合的副本并致电allNodes.Remove(key);
foreach (var key in allNodes.Keys.ToList())
{
allNodes.Remove(key);
}
要回答您的问题的附录,是SortedDictionary
(任何Dictionary
的问题)将不会处理重复的密钥 - 如果您尝试添加具有现有密钥的项目,它将< em>覆盖之前的值。
你可以使用SortedDictionary<float, List<Node<T>>>
但是你有复杂的提取集合与项目,需要初始化每个列表而不仅仅是添加项目,这一切都是可能的,并且可能仍然是添加和获取的最快结构,但它确实增加了一些复杂性。
答案 1 :(得分:2)
是的,你的复杂性是正确的。
在SortedDictionary
中,所有键都已排序。如果你想从最小到最大迭代,foreach
就足够了:
foreach(KeyValuePair<float, Node<T>> kvp in allNodes)
{
// Do Something...
}
您写道,您要删除项目。在使用foreach
进行迭代期间禁止从集合中删除,因此首先要创建它的副本。
编辑:
是的,如果您有重复的密钥,则无法使用SortedDictionary
。使用Node<T>
和float
创建结构节点,然后编写比较器:
public class NodeComparer : IComparer<Node>
{
public int Compare(Node n1, Node n2)
{
return n2.dist.CompareTo(n1.dist);
}
}
然后将所有内容放在简单的List<Node> allNodes
中并排序:
allNodes.Sort(new NodeComparer());
答案 2 :(得分:0)
由于Dictionary<TKey, TValue>
必须有唯一密钥,我会改用List<Node<T>>
。例如,如果您的Node<T>
类具有Value
属性
class Node<T>
{
float Value { get; set; }
// other properties
}
并且您希望按此属性排序,请使用LINQ:
var list = new List<Node<T>>();
// populate list
var smallest = list.OrderBy(n => n.Value).FirstOrDefault();
要逐个删除节点,只需迭代抛出列表:
while (list.Count > 0)
{
list.RemoveAt(0);
}