哈希表操作O(1)适用于哪种数据?


18

(何时)的答案是哈希表查找O(1)?,我收集到,当数据满足某些统计条件时,哈希表具有最坏情况的行为,至少已摊销,并且有一些技术可以使这些条件变宽。O(1)

但是,从程序员的角度来看,我事先并不知道我的数据是什么:它通常来自某些外部来源。而且我很少一次拥有所有数据:插入和删除的发生率经常不低于查找率,因此需要对数据进行预处理以微调哈希函数。

因此,迈出一步:在掌握了有关数据源的一些知识之后,如何确定哈希表是否有机会进行操作,以及可能在哈希函数上使用哪些技术?O(1)


哦,哈希表与二叉树是相关的,但是这里我主要关注哈希表以及它们何时(或不是)处于最佳状态。
吉尔斯(Gilles)'所以

对于任何哈希函数,最好的情况是数据均匀分布。
0x0

@Sunil:不对。您可以量身定制哈希函数。
拉斐尔

我认为这个问题太广泛了。特别是,您可以具体化关于数据源的知识是什么样的吗?
拉斐尔

@Raphael例如,如果该键是字符串:人的名,文件名中的目录,XML标签,文件哈希,...
吉尔“SO-停止作恶”

Answers:


4

有几种技术可以保证查找总是需要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)查找(即使在最坏的情况下),哈希表技术也会选择新功能并进行重新哈希处理,这些技术包括:

  • 布谷鸟哈希确保每个键查找最多成功进行2次哈希计算和2次表查找。
  • 跳房子散列保证在检查表中的小数H(可能是H = 32)的连续条目之后,每个键查找都会成功。
  • 动态完美散列 -1994年Dietzfelbinger撰写的论文是我读过的第一篇论文,指出即使为了确保每次键查找总是成功进行2次散列计算和2次查找而“频繁地”刷新,它还是有可能的进行一次完整的重新哈希的操作很少,即使每次完整的重新哈希使用的时间为O(n),插入和删除的预期平均成本也要摊销O(1)。

数据结构/哈希表



5

对于静态集,哈希表查找始终可以为,请参阅Arne Andersson和Mikkel Thorup在2002年发表的论文:具有指数搜索树的动态有序集O(1)

首先,我们给出了第一种确定性的多项式时间(in n)算法,该算法以 最坏情况的访问成本(参见完美哈希)构造线性空间静态字典。如前所述,可以在最坏的情况下以O n 2 W 不分割的方式构造一个恒定时间支持成员查询(不支持邻居查询)的线性空间数据结构[30]。我们表明可以消除单词大小的依赖性。O(1)O(n2W)

在一般情况下,Andersson等人提供了一种用于哈希索引数据结构的算法,该算法支持在O(logn/loglogn)O(1)


5

ha,b(x)=ax+bmodp

过去,根据Crosby和Wallach撰写的Usenix论文,常见的编程语言无法做到这一点,而使许多Web应用程序(和其他服务器)容易因制造冲突而遭受DoS攻击。(该论文来自2003年,但它暗示丹·伯恩斯坦(Dan Bernstein)早就发现了这个想法。)

谷歌的快速搜索提供了在实现方面的最新技术水平的改善未改善的主张。

另一个问题是,在高带宽的世界中,定时攻击使得在网上找到冲突不是那么困难(与Crosby-Wallach链接所暗示的离线相比)。我似乎记得,丹尼尔·戈洛文(Daniel Golovin)几年前在不易受到定时攻击的数据结构上取得了成果,但我不知道它们是否被广泛使用。


0

哈希表的平均用例分析是在输入均一性的通常假设下进行的,该假设以前是由于occam的剃刀造成的。

如果您对域和键的分布有更多的了解,则可以进行相同的平均情况分析,并用分布替换均匀分布,并至少从理论上重新计算期望值。

当然,困难源于难以进行不均匀的用例分析的事实。而且,您的“知识”可能无法方便地表达为易于在此类分析中使用的分布。

显然,最简单的方法是模拟。实现哈希表,并观察它们对典型输入集的性能。


8
我不同意第一句话。标准假设是哈希函数是随机的,而不是输入数据。假设数据分布均匀,则将分析推入幻想的境界-现实世界中的数据永远不会统一!但是,有一些教科书技术可以使散列函数足够均匀。请参阅通用哈希,尤其是制表哈希
JeffE 2012年

@JeffE看一下Raphael答案中的平均情况分析,他陈述了这种均匀性假设。没有分布就无法进行平均案例分析。您必须选择一个,如果未给出,则occam的剃刀建议使用统一的一个。
乌里2012年

6
当然,您有发行版;这是您用来选择哈希函数的分布。选择输入数据的分布就像在灯柱下寻找丢失的钥匙一样。当然,光线会更好,但是那可能不是您放下它们的地方。
JeffE 2012年

@JeffE这就是完成平均情况分析的方式,选择一个分布并开始计算。与往常一样,分配的选择值得商bat。非常欢迎您进行非均匀的平均情况分析。
乌里

4
是的,我知道怎么做。(检查我的个人资料。)如果您希望分析具有预测性(这是分析的重点),则必须随机化哈希函数。然后,您会知道精确的分布,因为您选择了它。
JeffE 2012年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.