在O(1)中实现具有密钥和基于索引的访问的哈希表

时间:2011-09-29 14:48:40

标签: c# list data-structures collections hashtable

.NET中有一个名为NameObjectCollectionBase的数据结构,我正在努力理解。

基本上,它允许输入任意string =>对象键/值对,键的可能性和值为null。密钥可以由多个对象使用。通过基于索引和基于字符串的访问授予访问权限,而基于字符串的访问仅返回具有指定键的第一个值。

他们所承诺的是

add(string, object)        O(1) if no relocation, O(n) otherwise
clear                      O(1)
get(int)                   O(1) corresponds to getkey(int)
get(string)                O(1) returns first object found with given key
getallkeys                 O(n) if objects share a key, it is returned that many times
getallvalues               O(n)
getallvalues(type)         O(n) returns only objects of a given type
getkey(int)                O(1) corresponds to get(int)
haskeys                    O(1) if there are objects with a non-null key
remove(string)             O(n) remove all objects of a given key
removeat(int)              O(n)
set(int, object)           O(1) 
set(string, object)        O(1) sets the value of the first found object with given key
getenumerator              O(1) enumerator over keys
copyto(array, int)         O(n) 

基于索引的访问与插入顺序无关。但是,get(int)getkey(int)必须相互排列。

我想知道如何实现结构。在O(1)中同时允许索引和基于密钥的访问似乎并非易事。他们在MSDN页面上声明“此类的底层结构是一个哈希表”。但是,C#哈希表不允许每个键有多个值,也不允许使用空键。

将它实现为Dictionary<string, List<object>似乎不是解决方案,因为get(string)将是O(1)但get(int)不是因为你必须遍历所有键以找出哪个键具有其中有很多项目。

将其实现为两个单独的列表,其中一个是键的简单List<string>,而List<Object>的值是Dictionary<string, int>的组合,每个键指向索引的{{1}}第一个值将允许O(1)中的两种类型的访问,但不允许以有效的方式删除,因为所有索引都必须在哈希表中更新(可能在O(n)中但似乎不是最好的解决方案)。或者是否有更有效的方法来删除条目?

如何实施这样的数据结构?

1 个答案:

答案 0 :(得分:1)

NameObjectCollectionBase使用Hashtable和Arraylist来管理条目。看看你自己!

Microsoft提供.NET库的参考源代码,可以集成到Visual Studio中:

http://referencesource.microsoft.com/

您甚至可以调试.NET库:

http://msdn.microsoft.com/en-us/library/cc667410(VS.90).aspx

或者您可以获取dotPeek的副本,这是一个免费的反编译器:

http://www.jetbrains.com/decompiler/