试图理解线性探测逻辑。
使用开放寻址作为哈希表,如何确认元素不在表中。
例如,假设你有一个10桶的hashmap。 假设您对一个键进行哈希,然后插入它。现在,如果要插入元素A和B并将其散列并减少到同一个桶,那么如果使用线性探测器,元素A和B可能会彼此相邻。
现在,仅仅因为存储桶为空,似乎并不意味着地图中不存在元素。例如首先删除元素A后搜索元素B.首先你得到一个你想要B的空桶,但是你需要再探测一个,你会找到B.它确实存在。如果该逻辑是正确的,那么您是否不必搜索整个表以确认密钥是否存在?即每次O(n)表现。
我所说的是,你不需要通过整个地图来真实地确认它不存在吗?
对hashmap采用单独的链接方法,该问题不存在。
编辑: 我的意思是看这张照片 http://upload.wikimedia.org/wikipedia/commons/b/bf/Hash_table_5_0_1_1_1_1_0_SP.svg
如果John Smith被删除,我们会尝试找到Sandra Dee。
或者使用线性寻址是为了移动元素,以便没有这样的孔。即如果John Smith被删除,那么152到154之间的元素会被移回一个地方吗?它在描述中并没有真正看到,但这可能会有所帮助。除非ted面包师散列到154,而不是如上所述153。需要比我想象的更多的工作。
可能只需在每个存储桶中使用简单的链接列表。
答案 0 :(得分:4)
在绝对最坏的情况下,是的确定某个项目是否在表格中的算法是O(n)。但是,这将永远不会发生在正确管理的哈希表中。
删除某个项目时,应将一个墓碑放置在已从中删除的表格槽中。墓碑只是一些数据,表明曾经有一个元素,但它已被删除。这样,每次搜索元素时,都必须遵循所使用的探测序列,直到找到空白的插槽。如果插槽为空,则表示您已完成该散列值的探测序列,并且知道它不会位于表中的任何其他位置。
您必须搜索探测序列中每个插槽的唯一方法是探测序列中是否没有空插槽。因为你应该总是将哈希表的目标设为半空,这不应该发生。
答案 1 :(得分:3)
使用解决与探测策略冲突的哈希表对数据结构的删除功能提出了严格的要求。删除项目时,必须补偿哈希表,使其仍满足搜索所需的要求(这是哈希表的主要要点)。
使用线性探测,如果删除项目,则移至下一个插槽。如果它与我们刚刚删除的插槽的哈希匹配,请移动它。冲洗并重复,直至到达空槽。还有一些延迟删除策略,其中项目被标记为删除,然后在下一次搜索时实际删除/补偿。
假设具有相同哈希值的三个项{A0,A1,A2}。设{A0,A1}在Hashtable中,{A2}不在。如果我们删除A0,我们将其标记为删除。当我们搜索A2(不在Hashtable中)时,我们找到A0(已删除),然后我们移动到A1,我们将其重新定位到A0的槽中,最终确定删除。我们移动到下一个插槽(可能是A2,或插槽A1的候选者刚占用),但发现它是空的,所以我们清除了A1刚刚腾出的插槽,我们的散列表又恢复到原始状态。
答案 2 :(得分:0)
我认为这已经晚了,但是有一个提到探针序列和哈希表的最大探测序列。
每次插入一个元素时,您确实记录了过去已经执行的探测最大数量,并且'maxProb'小于插入当前元素所使用的探测数量。
最后,当您在哈希表中搜索元素时,您将只执行最多的maxProb搜索。
现在考虑到你不允许无限或N个探测,其中N是散列表的容量,运行时间将是O(x),其中x是最坏情况下允许的最大探测。
假设您的哈希密钥生成算法强制您多次进行探测,那么您可以通过这种方式实现数据结构,如果插入需要x探测,则应考虑重新哈希本身。强>