在.NET中,通过字符串键或数字索引进行查找的最佳数据结构是什么?

在.NET中,通过字符串键或数字索引进行查找的最佳数据结构是什么?,.net,data-structures,collections,ordereddictionary,.net,Data Structures,Collections,Ordereddictionary,我正在寻找最理想的数据结构(为了性能和易用性),从中可以通过字符串键或索引检索值。字典不起作用,因为您无法真正按索引检索。有什么想法吗?基于哈希的集合(字典、哈希表、哈希集)已经过时,因为您没有索引,因为您需要索引,所以我会使用嵌套的泛型: List<KeyValuePair<K,V>> 列表 当然,您会丢失通过哈希得到的O(1)键查找。还有System.Collections.ObjectModel。KeyedCollection,它派生自Collection检索为

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

基于哈希的集合(字典、哈希表、哈希集)已经过时,因为您没有索引,因为您需要索引,所以我会使用嵌套的泛型:

List<KeyValuePair<K,V>>
列表

当然,您会丢失通过哈希得到的O(1)键查找。

还有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
{字典键=新字典();
受保护的重写字符串GetKeyForItem(TItem项){返回键[item];}
公共无效添加(字符串键,TItem项)
{键[项]=键;
本条增加(项目);
}
}

您正在寻找类似的内容(这也是)。

您想要这个类。您需要包括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"]);

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

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

如果不经常按索引进行检索,则
SortedList
SortedDictionary
将具有更好的性能特征(可通过
元素扩展方法实现索引访问)

另一方面,如果按索引访问是标准,那么停止同时使用字典数据结构,只需将值存储在
列表中即可。尽管这意味着按键线性搜索访问权限,但所有其他操作都非常便宜,而且在实践中很难击败总体性能


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

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

我建议使用SortedDictionary或SortedList。两者都有O(logn)搜索性能

这些差异是 委员会:

SortedList)使用更少的内存 而不是分类词典)

SortedDictionary)具有更快的插入速度和 未排序数据的删除操作: O(对数n)与O(n)相对 分类列表)

如果列表一次全部填充 从已排序的数据中,SortedList)比 分类词典)



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

KeyedCollection是一个抽象类,他必须在其中的一个上实现一个键/值集合。您只需为KeyedCollection实现GetKeyForItem(),如果对象包含其键,则使用KeyedCollection几乎肯定是最佳选择,因为您将提取密钥的逻辑封装在一个函数中,而不是在使用集合的任何地方。这太可怕了。列表给出了O(n)检索,而SortedList或SortedDictionary给出了O(logn)。SortedList还意味着索引没有价值。另外,GetByIndex是一个O(N)查找,这不是通用的。请查看SortedList或SortedDictionary泛型类以获得最佳性能。如果性能足够,OrderedDictionary满足问题中所述的所有要求,并且只有在实施后才能确定。好,但是很难想象为什么有些人会选择这个而不是一个通用选项,除非他们使用.NET 1.0或.NET 1.1。很好的发现,这似乎是唯一保留索引的键/值集合。没有数字索引器,所以你必须使用list.Values[i],或者你可以只使用GetByIndex()方法。我在看通用版本。SortedList不会保留项目的原始顺序,它会按照键的顺序对项目进行排序。虽然我可能错了,因为这个问题在这方面有点含糊不清。他要求一些可以通过键或索引访问的东西。没有提到订单。我真的对这个问题的一些答案感到惊讶。仔细考虑后,它可能会很糟糕,因为我想它需要枚举到那个索引。如果他必须有一个O(N),那么有一个索引有什么意义查找时间?System.Collections.ObjectModel.KeyedCollection使用字典您不能相信索引在sortedList或sortedDictionary中保持不变。在数据操作过程中可能发生变化的索引有什么好处?