散列如何具有 o(1) 搜索时间? [复制]
Posted
技术标签:
【中文标题】散列如何具有 o(1) 搜索时间? [复制]【英文标题】:How does hashing have an o(1) search time? [duplicate] 【发布时间】:2011-05-20 19:07:37 【问题描述】:当我们使用HashTable
存储数据时,据说搜索需要o(1) 时间。我很困惑,谁能解释一下?
【问题讨论】:
hashTable 中的查找成本是一个摊销常数 O(1)——大多数时候我们只做恒定的工作,但偶尔(有冲突的地方)我们会做一些直接比较,这可以再次成为二分或线性搜索。 【参考方案1】:如果哈希表中没有冲突,则搜索需要 O(1) 时间,因此 sya 认为在哈希表中搜索需要 O(1) 或恒定时间是不正确的。
See how Hashtable works on MSDN?
编辑
mgiuca 很好地解释了它,我只是添加了一种称为链接的碰撞避免技术。
在这种技术中,我们在每个位置维护一个值的链接列表,因此当您有碰撞时,您的值将被添加到该位置的链接列表中,因此当您搜索值时,您可能需要搜索整个链接列表中的值,这样在这种情况下搜索将不是 O(1) 操作。
【讨论】:
【参考方案2】:嗯,这是一个小的谎言——它可能需要更长的时间,但通常不会。
基本上,哈希表是一个包含所有要搜索的键的数组。数组中每个键的位置由 散列函数 确定,该函数可以是始终将相同输入映射到相同输出的任何函数。我们假设散列函数是O(1)。
所以当我们在哈希表中插入一些东西时,我们使用哈希函数(我们称之为h)来找到放置它的位置,并把它放在那里。现在我们插入另一个东西,散列和存储。还有一个。每次我们插入数据,都需要 O(1) 的时间来插入(因为哈希函数是 O(1)。
查找数据是一样的。如果我们想找到一个值,x,我们只需要找出h(x),它告诉我们x在哪里哈希表。所以我们也可以在 O(1) 中查找任何哈希值。
现在说谎:上面是一个非常好的理论,但有一个问题:如果我们插入数据并且数组的那个位置已经有东西怎么办?没有什么可以保证散列函数不会为两个不同的输入产生相同的输出(除非你有一个perfect hash function,但这些很难产生)。因此,当我们插入时,我们需要采取以下两种策略之一:
在数组的每个位置存储多个值(例如,每个数组槽都有一个链表)。现在,当您进行查找时,到达数组中的正确位置仍然是 O(1),但可能是线性搜索(希望是短的)链表。这称为“分离链接”。 如果您发现某些东西已经存在,请再次散列并找到另一个位置。重复直到你找到一个空的地方,然后把它放在那里。查找过程可以遵循相同的规则来查找数据。现在到达第一个位置仍然是 O(1),但是有一个潜在的(希望是短的)线性搜索在桌子周围反弹,直到找到你想要的数据。这称为“开放寻址”。基本上,这两种方法仍然大部分 O(1),但具有希望短的线性序列。对于大多数目的,我们可以假设它是 O(1)。如果哈希表太满,那些线性搜索会变得越来越长,然后是时候“重新哈希”了,这意味着创建一个更大的新哈希表并将所有数据重新插入其中.
【讨论】:
非常感谢您的解释.. +1 :为了更好地解释它,还有其他技术也可以避免冲突,例如“字典基本上使用链式,双散列等。” @user531802 没问题。如果您对这个答案感到满意,您是否可以勾选“接受的答案”复选框? 哇 --- 所以哈希是数组 index,而不是线性搜索索引? 对此进行很好的解释-the hash table is getting too full, those linear searches can become longer and longer, and then it is time to "re-hash" which means to create a new hash table of a much bigger size
检查-***.com/questions/2369467/…以上是关于散列如何具有 o(1) 搜索时间? [复制]的主要内容,如果未能解决你的问题,请参考以下文章