如何在c#中正确使用SortedDictionary?

时间:2013-04-17 20:19:15

标签: c# dictionary sorted sorteddictionary

我正在尝试做一些非常简单的事情,但似乎我不理解SortedDictionary

我要做的是以下几点:
创建一个排序字典,按照某个浮点数对我的项目进行排序,因此我创建了一个类似于此字典的字典

SortedDictionary<float, Node<T>> allNodes = new SortedDictionary<float, Node<T>>();

现在我添加项目后,我想逐个删除它们(每次删除都应该从最小到最大的复杂度为O(log(n))。

我该怎么办?我认为只是allNodes[0]会给我最小的,但事实并非如此。

此外,似乎字典无法处理重复键。我觉得我使用的是错误的数据结构...... 如果我有一堆节点要按其距离(浮点)排序,我应该使用其他东西吗?

3 个答案:

答案 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);
}