如何在 C# 中正确使用 SortedDictionary?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16069515/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to properly use SortedDictionary in c#?
提问by OopsUser
I'm trying to do something very simple but it seems that I don't understand SortedDictionary.
我正在尝试做一些非常简单的事情,但似乎我不明白SortedDictionary。
What I'm trying to do is the following:
Create a sorted dictionary that sorts my items by some floating number, so I create a dictionary that looks like this
我想要做的是以下内容:
创建一个排序的字典,按一些浮点数对我的项目进行排序,所以我创建了一个看起来像这样的字典
SortedDictionary<float, Node<T>> allNodes = new SortedDictionary<float, Node<T>>();
And now after I add items, I want to remove them one by one (every removal should be at a complexity of O(log(n)) from the smallest to the largest.
现在在我添加项目之后,我想将它们一个一个地删除(每次删除的复杂度应该是 O(log(n)) 从最小到最大。
How do I do it? I thought that simply allNodes[0]will give me the the smallest, but it doesn't.
我该怎么做?我认为这只allNodes[0]会给我最小的,但事实并非如此。
More over, it seems like the dictionary can't handle duplicate keys. I feel like I'm using the wrong data structure...
Should I use something else if I have bunch of nodes that I want to be sorted by their distance (floating point)?
更重要的是,字典似乎无法处理重复的键。我觉得我使用了错误的数据结构......
如果我有一堆要按距离(浮点)排序的节点,我应该使用其他东西吗?
采纳答案by D Stanley
allNodes[0]will not give you the first item in the dictionary - it will give you the item with a floatkey valueof 0.
allNodes[0]不会为您提供字典中的第一项 - 它会为您提供float键值为0.
If you want the first item try allNodes.Values.First()instead. Or to find the first keyuse allNodes.Keys.First()
如果您想要第一个项目,请尝试allNodes.Values.First()。或者找到第一个键使用allNodes.Keys.First()
To removethe items one by one, loop over a copyof the Keyscollection and call allNodes.Remove(key);
要删除一个项目一个,遍历一个副本中的Keys采集和呼叫allNodes.Remove(key);
foreach (var key in allNodes.Keys.ToList())
{
allNodes.Remove(key);
}
To answer your addendum to your question, yes SortedDictionary(any flavor of Dictionaryfor that matter) will not handle duplicate keys - if you try and add an item with an existing key it will overwritethe previous value.
要回答您的问题的附录,是的SortedDictionary(任何形式的Dictionary)都不会处理重复的键 - 如果您尝试使用现有键添加项目,它将覆盖以前的值。
You could use a SortedDictionary<float, List<Node<T>>>but then you have the complexity of extracting collectionsversus items, needing to initializeeach list rather than just adding an item, etc. It's all possible and may still be the fastest structure for adds and gets, but it does add a bit of complexity.
你可以使用 aSortedDictionary<float, List<Node<T>>>但是你有提取集合与项目的复杂性,需要初始化每个列表而不是仅仅添加一个项目等等。这一切都是可能的,并且可能仍然是添加和获取最快的结构,但它确实添加了一个有点复杂。
回答by Linus Caldwell
As a Dictionary<TKey, TValue>must have unique keys, I'd use List<Node<T>>instead. For instance, if your Node<T>class has a Valueproperty
由于Dictionary<TKey, TValue>必须具有唯一键,我会使用它List<Node<T>>。例如,如果您的Node<T>班级有一个Value属性
class Node<T>
{
float Value { get; set; }
// other properties
}
and you want to sort by this property, use LINQ:
并且您想按此属性排序,请使用 LINQ:
var list = new List<Node<T>>();
// populate list
var smallest = list.OrderBy(n => n.Value).FirstOrDefault();
To remove the nodes one by one, just iterate threw the list:
要一个一个删除节点,只需迭代抛出列表:
while (list.Count > 0)
{
list.RemoveAt(0);
}
回答by Peter
Yes, you're right about complexity.
是的,您对复杂性是正确的。
In SortedDictionaryall the keys are sorted. If you want to iterate from the smallest to the largest, foreachwill be enough:
在SortedDictionary所有的键都排序。如果你想从最小到最大迭代,foreach就足够了:
foreach(KeyValuePair<float, Node<T>> kvp in allNodes)
{
// Do Something...
}
You wrote that you want to remove items. It's forbidden to remove from collections during iteratation with foreach, so firstly create a copy of it to do so.
您写道要删除项目。在迭代过程中禁止从集合中移除foreach,因此首先创建它的副本来这样做。
EDIT:
编辑:
Yes, if you have duplicated keys you can't use SortedDictionary. Create a structural Node with Node<T>and float, then write a comparer:
是的,如果您有重复的密钥,则不能使用SortedDictionary. 使用Node<T>和创建一个结构节点float,然后编写一个比较器:
public class NodeComparer : IComparer<Node>
{
public int Compare(Node n1, Node n2)
{
return n2.dist.CompareTo(n1.dist);
}
}
And then put everything in simple List<Node> allNodesand sort:
然后把所有东西都放在简单List<Node> allNodes和排序中:
allNodes.Sort(new NodeComparer());

