【问题标题】:How to properly use SortedDictionary in c#?如何在 C# 中正确使用 SortedDictionary?
【发布时间】:2013-04-10 18:35:34
【问题描述】:

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

我正在尝试执行以下操作:
创建一个排序字典,按某个浮点数对我的项目进行排序,所以我创建了一个看起来像这样的字典

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

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

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

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

【问题讨论】:

  • 字典键值必须是唯一的。我认为您想使用 List> 代替,因为 Lists 可以有重复的条目。然后使用 LINQ 将数据按照您希望的顺序进行操作。
  • 您只是想根据每个节点的某些值对节点集合进行排序,还是出于某些特殊原因需要使用SortedDictionary?如果是前者,只需在您开始时的集合上使用 LINQ OrderBy
  • 我想在 O(Log(n)) 中插入和删除,我的大部分工作是插入和删除......哪个列表在 O(N) 中完成。对于您的问题:排序基于每个节点中的某些值。

标签: c# dictionary sorted sorteddictionary


【解决方案1】:

allNodes[0] 不会为您提供字典中的第一个项目 - 它会为您提供 float 键值0 的项目。

如果您想要第一项,请尝试使用allNodes.Values.First()。或者找到第一个 key 使用allNodes.Keys.First()

要逐个删除项目,循环遍历Keys集合的副本并调用allNodes.Remove(key);

foreach (var key in allNodes.Keys.ToList())
{
    allNodes.Remove(key);
}

要回答您对问题的补充,是的 SortedDictionaryDictionary 的任何风格)将不会处理重复的密钥 - 如果您尝试使用现有密钥添加项目,它将 覆盖 之前的值。

您可以使用SortedDictionary&lt;float, List&lt;Node&lt;T&gt;&gt;&gt;,但您会遇到提取集合与项目的复杂性,需要初始化每个列表,而不仅仅是添加一个项目等。这一切都是可能的,并且可能仍然是添加和获取的最快结构,但它确实增加了一些复杂性。

【讨论】:

    【解决方案2】:

    是的,关于复杂性,你是对的。

    SortedDictionary 中,所有键都已排序。如果你想从最小到最大迭代,foreach 就足够了:

    foreach(KeyValuePair<float, Node<T>> kvp in allNodes)
    {
        // Do Something...
    }
    

    您写过要删除项目。禁止在使用foreach 进行迭代期间从集合中删除,因此请先创建它的副本。

    编辑:

    是的,如果您有重复的密钥,则不能使用SortedDictionary。用Node&lt;T&gt;float创建一个结构节点,然后写一个比较器:

    public class NodeComparer : IComparer<Node>
    {
        public int Compare(Node n1, Node n2)
        {
            return n2.dist.CompareTo(n1.dist);
        }
    }
    

    然后将所有内容放入简单的List&lt;Node&gt; allNodes 并排序:

    allNodes.Sort(new NodeComparer());
    

    【讨论】:

      【解决方案3】:

      由于Dictionary&lt;TKey, TValue&gt; 必须有唯一的键,我会改用List&lt;Node&lt;T&gt;&gt;。例如,如果您的 Node&lt;T&gt; 类具有 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);
      }
      

      【讨论】:

        猜你喜欢
        • 2010-10-01
        • 1970-01-01
        • 2021-07-16
        • 2020-08-26
        • 2013-08-26
        • 1970-01-01
        • 2015-07-12
        相关资源
        最近更新 更多