为什么带链表的哈希表被认为具有恒定的时间复杂度?

时间:2017-04-07 23:45:02

标签: java hash time-complexity hashtable

在昨晚的COMP课程中,我们了解了哈希以及在哈希表中找到元素 x 时它通常如何工作。

我们的场景是我们的表中有一个1000个元素的数据集,我们想知道该表中是否包含 x

我们的教授绘制了一个100的Java数组,并说要存储这1000个元素,数组的每个位置都会包含一个指向链接列表的指针,我们会保留这些元素。

假设散列函数将1000个元素中的每个元素完美地映射到0到99之间的值并将元素存储在数组中的位置,则每个链接列表中将包含1000/100 = 10个元素。

现在要知道 x 是否在表中,我们只需哈希 x ,找到它的哈希值,在该槽位查找数组并迭代在我们的链接列表上检查 x 是否在表格中。

我的教授最后说,找到 x 是否在表中的预期复杂性是O(10),它实际上只是O(1)。我无法理解这是怎么回事。在我看来,如果数据集是N并且数组大小是n,那么在表中找到 x 的平均N / n步骤。根据定义,这不是恒定的时间,因为如果我们扩大数据集的时间仍会增加吗?

我已经查看了Stack Overflow和在线,并且每个人都说散列是O(1)的时间复杂度,但有一些警告。我读过人们讨论链接以减少这些警告。也许我错过了确定时间复杂性的基本原则。

TLDR:为什么在哈希表中查找值时,为什么还需要O(1)时间来确定数据集的大小(因此是N的函数,因此不是常数)。

3 个答案:

答案 0 :(得分:3)

  

在我看来,如果数据集为N且数组大小为n,那么在表中找到x需要平均N / n步。

这是一种误解,因为散列只需要您计算应该存储对象的正确存储桶(在本例中为数组索引)。如果数据集的大小发生更改,则此计算不会变得更复杂

您所说的这些警告很可能是哈希冲突:多个对象共享相同的hashCode;这些可以通过更好的哈希函数来防止。

答案 1 :(得分:1)

用于查找的散列集合的复杂性是O(1),因为每个存储桶的列表(或在Java的情况下,红黑树)的大小不依赖于N.最坏情况的性能为HashMap如果你有一个非常糟糕的哈希函数是O(log N),但正如Javadocs指出的那样,你得到O(1)性能"假设哈希函数在桶之间正确地分散元素&# 34 ;.通过适当的分散,每个桶的集合的大小或多或少是固定的,并且还足够小,使得常数因子通常压倒多项式因子。

答案 2 :(得分:1)

这里有多个问题,所以我将逐一解决这些问题:

最差案例分析与摊销分析:

最坏情况分析是指绝对最坏的情况,您的算法可以相对于运行时间给出。作为一个例子,如果我给出一个无序元素的数组,并且我被告知在其中找到一个元素,我最好的情况是当元素在索引[0]时,我可以给出的最糟糕的事情就是当元素位于数组的末尾,在这种情况下,如果我的数据集是n,我在找到元素之前运行n次。然而,在平均情况下,元素是数组中的任何位置,因此我将运行n-k步(其中k是我在数组中查找的元素之后的元素数)。

最糟糕的Hashtables案例分析: 只存在一种Hashtable,它保证了对它的元素Arrays的恒定时间访问O(1)。 (即使这样,分页和OS处理内存的方式也不是真的。)我可以给你一个哈希表的最糟糕的情况是一个数据集,其中每个元素哈希到相同的索引。因此,例如,如果由于冲突,每个单元素哈希到索引1,则访问值的最坏情况运行时间是O(n)。这是不可避免的,哈希表总是有这种行为。

哈希表的平均和最佳情况: 你将很少得到一个给你最糟糕情况的集合。通常,您可以期望将对象散列到散列表中的不同索引。理想情况下,散列函数以非常分散的方式散列事物,以便将对象散列到散列表中的不同索引。

在您的老师给您的具体示例中,如果有两件事情被归入同一索引,则会将其放入链接列表中。所以这或多或少是表格的构建方式:

get element E
use the hashing function hash(E) to find the index i in the hash table
add e to the linjed list in hashTable[i].

repeat for all the elements in the data set

现在,让我们说我想找出元素E是否在桌面上。然后:

do hash(E) to find the index i where E is potentially hashed

go to hashTable[i] and iterate through the linked list (up to 10 iterations)

If E is found, then E is in the Hash table, if E is not found, then E is not in the table

如果我们找不到它,我们可以保证E不在表中的原因是因为如果它是,它将被哈希到hashTable [i]所以它必须在那里,如果它在桌子。