【问题标题】:Implementing hash table with both key and index-based access in O(1)在 O(1) 中实现具有基于键和基于索引的访问的哈希表
【发布时间】:2011-11-27 18:53:27
【问题描述】:

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

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

他们承诺的是

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> 将每个键指向第一个值的索引将允许两者O(1) 中的访问类型,但不允许以有效的方式删除,因为必须在哈希表中更新所有索引(在 O(n) 中可能,但似乎不是最佳解决方案)。还是有更有效的方法来删除条目?

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

【问题讨论】:

    标签: c# list data-structures collections hashtable


    【解决方案1】:

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

    微软提供 .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/

    【讨论】:

    • 由于我想在商业项目中构建类似的数据结构,我可能不会使用参考源。 “许可证禁止所有源代码的使用,而不是出于参考目的查看代码。”我认为不允许复制/粘贴或基于它的代码。但你的回答似乎支持我的第二个想法。
    • 我不打算让您简单地复制和粘贴代码。审查实现比猜测类可能在做什么要有用得多。从他们的方法中学习,也许在那里发现的概念可能对您自己的实施有用。
    猜你喜欢
    • 2021-04-06
    • 1970-01-01
    • 2014-01-22
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    • 2013-02-08
    • 2016-06-15
    • 2015-07-19
    相关资源
    最近更新 更多