【问题标题】: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
    相关资源
    最近更新 更多