从(何时)的答案是哈希表查找O(1)?,我收集到,当数据满足某些统计条件时,哈希表具有最坏情况的行为,至少已摊销,并且有一些技术可以使这些条件变宽。
但是,从程序员的角度来看,我事先并不知道我的数据是什么:它通常来自某些外部来源。而且我很少一次拥有所有数据:插入和删除的发生率经常不低于查找率,因此需要对数据进行预处理以微调哈希函数。
因此,迈出一步:在掌握了有关数据源的一些知识之后,如何确定哈希表是否有机会进行操作,以及可能在哈希函数上使用哪些技术?
从(何时)的答案是哈希表查找O(1)?,我收集到,当数据满足某些统计条件时,哈希表具有最坏情况的行为,至少已摊销,并且有一些技术可以使这些条件变宽。
但是,从程序员的角度来看,我事先并不知道我的数据是什么:它通常来自某些外部来源。而且我很少一次拥有所有数据:插入和删除的发生率经常不低于查找率,因此需要对数据进行预处理以微调哈希函数。
因此,迈出一步:在掌握了有关数据源的一些知识之后,如何确定哈希表是否有机会进行操作,以及可能在哈希函数上使用哪些技术?
Answers:
有几种技术可以保证查找总是需要O(1)操作,即使在最坏的情况下也是如此。
如何确定哈希表是否有机会进行O(1)操作,以及可能在哈希函数上使用哪些技术?
最糟糕的情况是某些恶意攻击者(Mallory)故意为您提供了Mallory特别选择的数据,以使系统运行缓慢。
选择了特定的哈希函数后,假设Mallory永远不会找出您选择的哈希函数可能就过于乐观了。一旦Mallory发现您选择了哪个哈希函数,如果您允许Mallory使用该哈希函数将大量数据插入到哈希表中,那么您就注定了:Mallory可以在内部快速生成数十亿个数据项,并使用哈希函数可找出可能发生冲突的数据项,然后向您提供数百万可能发生冲突的千分之一数据项,从而导致查找工作比O(1)慢得多。
所有保证“即使在最坏的情况下也可以进行O(1)查找”的技术通过对每次插入进行一些额外的工作来避免将来出现此问题,以保证将来所有可能的查找都能在O(1)时间内成功进行。 。特别是,我们假设(最坏的情况)Mallory迟早会发现我们正在使用哪个哈希函数;但是他只有机会在我们选择其他散列函数(制表散列或某些其他通用散列)之前插入一些数据项,我们特别选择了其中一项,以便可以在2中查找到目前为止的所有数据。或3个探针-即O(1)。由于我们随机选择此功能,因此可以肯定地说,马洛里一会儿不会知道我们选择了什么功能。即使马洛里立即提供给我们的数据,即使有了这个新的哈希函数,它也会与先前的数据发生冲突,然后我们可以选择另一个新的哈希函数,以便在重新哈希后,现在可以查看他和其他人提供给我们的所有先前数据在最坏的情况下最多2或3个探针-即在最坏的情况下进行O(1)查找。
随机选择一个新的哈希函数并足够频繁地重新哈希整个表以保证每次查找始终为O(1)是相当容易的。尽管这样可以保证每次查找始终为O(1),但是当将第N个项目插入已经包含N-1个项目的哈希表中时,这些技术有时可能需要O(N)时间进行该插入。但是,可以对系统进行设计,以使即使Mallory故意为您提供新数据,并且使用新的哈希函数与之前的数据发生冲突,该系统也可以在需要执行以下操作之前接受Mallory和其他项目中的许多项目完全O(N)重建。为了保证O(1)查找(即使在最坏的情况下),哈希表技术也会选择新功能并进行重新哈希处理,这些技术包括:
对于静态集,哈希表查找始终可以为,请参阅Arne Andersson和Mikkel Thorup在2002年发表的论文:具有指数搜索树的动态有序集
首先,我们给出了第一种确定性的多项式时间(in n)算法,该算法以 最坏情况的访问成本(参见完美哈希)构造线性空间静态字典。如前所述,可以在最坏的情况下以O (n 2 W )不分割的方式构造一个恒定时间支持成员查询(不支持邻居查询)的线性空间数据结构[30]。我们表明可以消除单词大小的依赖性。
在一般情况下,Andersson等人提供了一种用于哈希索引数据结构的算法,该算法支持在
过去,根据Crosby和Wallach撰写的Usenix论文,常见的编程语言无法做到这一点,而使许多Web应用程序(和其他服务器)容易因制造冲突而遭受DoS攻击。(该论文来自2003年,但它暗示丹·伯恩斯坦(Dan Bernstein)早就发现了这个想法。)
谷歌的快速搜索提供了在实现方面的最新技术水平的改善和未改善的主张。
另一个问题是,在高带宽的世界中,定时攻击使得在网上找到冲突不是那么困难(与Crosby-Wallach链接所暗示的离线相比)。我似乎记得,丹尼尔·戈洛文(Daniel Golovin)几年前在不易受到定时攻击的数据结构上取得了成果,但我不知道它们是否被广泛使用。
哈希表的平均用例分析是在输入均一性的通常假设下进行的,该假设以前是由于occam的剃刀造成的。
如果您对域和键的分布有更多的了解,则可以进行相同的平均情况分析,并用分布替换均匀分布,并至少从理论上重新计算期望值。
当然,困难源于难以进行不均匀的用例分析的事实。而且,您的“知识”可能无法方便地表达为易于在此类分析中使用的分布。
显然,最简单的方法是模拟。实现哈希表,并观察它们对典型输入集的性能。