【问题标题】:What is the best data structure in .NET for look-up by string key or numeric index?.NET 中通过字符串键或数字索引查找的最佳数据结构是什么?
【发布时间】:2010-09-13 08:35:48
【问题描述】:

我正在寻找最理想的数据结构(为了性能和易用性),可以通过字符串键或索引从中检索值。字典不起作用,因为您无法真正按索引检索。有什么想法吗?

【问题讨论】:

    标签: .net data-structures collections ordereddictionary


    【解决方案1】:

    基于哈希的集合(字典、哈希表、哈希集)已经过时了,因为你没有索引,因为你想要一个索引,我会使用嵌套泛型:

    List<KeyValuePair<K,V>>
    

    当然,您会丢失使用散列获得的 O(1) 密钥查找。

    【讨论】:

    • 这太可怕了。 List 为您提供 O(n) 检索,而 SortedList 或 SortedDictionary 为您提供 O(log n)。
    • 一个 sortedList 也意味着索引没有价值。此外,GetByIndex 是 O(N) 查找。
    【解决方案2】:

    有 System.Collections.ObjectModel.KeyedCollection,它派生自 Collection检索是 O(1)

    class IndexableDictionary<TItem> : KeyedCollection<string, TItem>
     { Dictionary<TItem, string> keys = new Dictionary<TItem, string>();
    
       protected override string GetKeyForItem(TItem item) { return keys[item];}
    
       public void Add(string key, TItem item) 
        { keys[item] = key;
          this.Add(item);
        }
     }
    

    【讨论】:

    • KeyedCollection 是一个抽象类,他必须在它之上实现一个 Key/Value 集合。
    • 您只需要为 KeyedCollection 实现 GetKeyForItem()
    • 如果对象包含其键,则使用 KeyedCollection 几乎肯定是最佳选择,因为您将提取键的逻辑封装在一个函数中,而不是在使用集合的任何地方。
    【解决方案3】:

    您正在寻找类似SortedList class 的东西(这里也是generic version)。

    【讨论】:

    • 没有数字索引器,所以你必须使用 list.Values[i]
    • 或者你可以只使用 GetByIndex() 方法。
    • 对。我在看通用版本。
    • SortedList 不会保留项目的原始顺序,它会按照键的顺序对它们进行排序。这似乎不像原始发布者正在寻找的语义,尽管我可能是错的,因为这个问题在这方面有点模棱两可。
    • 他要求一些可以通过键或索引访问的东西。没有提及订单。我对这个问题的一些答案感到非常惊讶。
    【解决方案4】:

    你想要OrderedDictionary 类。您需要包含 System.Collections.Specialized 命名空间:

        OrderedDictionary od = new OrderedDictionary(); 
        od.Add("abc", 1); 
        od.Add("def", 2); 
        od.Add("ghi", 3); 
        od.Add("jkl", 4); 
    
        // Can access via index or key value:      
        Console.WriteLine(od[1]);       
        Console.WriteLine(od["def"]);
    

    【讨论】:

    • 这不是通用的。请查看 SortedList 或 SortedDictionary 泛型类以获得最佳性能。
    • OrderedDictionary 满足问题中所述的所有要求,如果性能足够,则只能在实施后确定。
    • 好的,但很难想象为什么有人会选择这个而不是通用选项,除非他们使用的是 .NET 1.0 或 .NET 1.1。
    • 好发现,这似乎是唯一保留其索引的键/值集合。
    【解决方案5】:

    一句警告。 OrderedDictionary 对于除了插入和查找之外的大多数操作确实性能不佳:删除和修改值都可能需要对整个列表进行线性搜索,从而导致运行时O em>(n)。 (对于修改,这取决于是按索引还是按键访问。)

    对于大多数具有合理数据量的操作,这是完全不可接受的。此外,该数据结构将元素存储在线性向量和哈希表中,导致一些内存开销。

    如果按索引检索不经常发生,SortedListSortedDictionary 将具有更好的性能特征(按索引访问可以通过ElementAt 扩展方法)。

    另一方面,如果按索引访问是常态,那么完全停止使用字典数据结构,只需将您的值存储在 List&lt;KeyValuePair&lt;TKey, TValue&gt;&gt; 中。虽然这意味着通过密钥进行线性搜索,但所有其他操作都非常便宜,并且在实践中整体性能难以超越。

    /EDIT:当然,后者也是理论上意义上的字典数据结构。您甚至可以将其封装在实现适当接口的类中。

    【讨论】:

    • 如果他必须有 O(N) 的查找时间才能获得索引,那么拥有索引有什么意义?
    • System.Collections.ObjectModel.KeyedCollection 使用字典
    【解决方案6】:

    字典可以与 linq 一起使用。虽然我不知道可能的性能问题。 Dictionary.ElementAt(index);

    【讨论】:

    • 在考虑之后,它可能很糟糕,因为我猜它需要枚举到那个索引。
    【解决方案7】:

    我推荐使用 SortedDictionary 或 SortedList。两者都有 O(log n) 的搜索性能。

    差异是,如引用自 MSDN library:

    排序列表)>) 使用更少的内存 比 SortedDictionary)>)。

    排序字典)>) 具有更快的插入和 未排序数据的删除操作: O(log n) 而不是 O(n) SortedList)>).

    如果列表一次全部填充 从排序数据,SortedList)>) 比 SortedDictionary)>)。

    根据我的经验,SortedDictionary 更适合大多数典型的业务场景,因为在使用这样的结构时,数据通常最初是未排序的,而且 SortedDictionary 的内存开销很少是关键的。但如果性能对您来说很关键,我建议您同时实施并进行测量。

    【讨论】:

    • 您不能相信索引在 sortedList 或 sortedDictionary 中保持不变。可能在数据操作中途发生变化的索引有什么用?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    • 2014-10-02
    • 2020-08-27
    • 1970-01-01
    相关资源
    最近更新 更多