在.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
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中保持不变。在数据操作过程中可能发生变化的索引有什么好处?