Algorithm 哈希表运行时复杂性(插入、搜索和删除)

Algorithm 哈希表运行时复杂性(插入、搜索和删除),algorithm,data-structures,hash,time-complexity,hashtable,Algorithm,Data Structures,Hash,Time Complexity,Hashtable,为什么我总是在哈希表上看到这些函数不同的运行时复杂性 在wiki上,搜索和删除是O(n)(我认为哈希表的目的是要有不断的查找,所以如果搜索是O(n),那又有什么意义呢) 在前一段时间的一些课程笔记中,我看到了各种各样的复杂性,这取决于某些细节,包括一个全部为O(1)的细节。如果我可以得到所有O(1),为什么还要使用其他实现 如果我使用C++或java语言中的标准哈希表,我能期望时间复杂性是多少?取决于如何实现哈希,最坏的情况下它可以转到O(n),在最好的情况下它是0(1)(一般来说,如果你的DS

为什么我总是在哈希表上看到这些函数不同的运行时复杂性

在wiki上,搜索和删除是O(n)(我认为哈希表的目的是要有不断的查找,所以如果搜索是O(n),那又有什么意义呢)

在前一段时间的一些课程笔记中,我看到了各种各样的复杂性,这取决于某些细节,包括一个全部为O(1)的细节。如果我可以得到所有O(1),为什么还要使用其他实现


如果我使用C++或java语言中的标准哈希表,我能期望时间复杂性是多少?

取决于如何实现哈希,最坏的情况下它可以转到O(n),在最好的情况下它是0(1)(一般来说,如果你的DS不是那么大,你可以实现)

也许你在看空间复杂度?这就是O(n)。其他复杂性与条目上的预期一样。随着存储桶数量的增加,搜索复杂度接近O(1)。如果在最坏的情况下,哈希表中只有一个bucket,那么搜索复杂度为O(n)


编辑回复评论我认为说O(1)是平均情况是不正确的。正如维基百科页面所说的那样,实际上是O(1+n/k),其中k是哈希表的大小。如果K足够大,那么结果就是O(1)。但是假设K是10,N是100。在这种情况下,每个bucket平均有10个条目,因此搜索时间肯定不是O(1);它是一个线性搜索,最多搜索10个条目。

理想情况下,哈希表是
O(1)
。问题是如果两个键不相等,但是它们会导致相同的散列

例如,假设字符串“it is best of times it is best of times”和“Green Eggs and Ham”都导致哈希值
123

当插入第一个字符串时,它被放入桶123中。当插入第二个字符串时,它将看到bucket
123
的值已经存在。然后将新值与现有值进行比较,发现它们不相等。在这种情况下,将为该键创建一个数组或链表。此时,检索该值变成
O(n)
,因为哈希表需要迭代该bucket中的每个值以找到所需的值

因此,在使用哈希表时,重要的是使用一个具有真正好的哈希函数的键,该哈希函数既快速又不会导致不同对象的重复值

有意义吗?

O(1)
平均和案例复杂度,但它受到
O(n)
最坏案例时间复杂度的影响。[我认为这就是你的困惑所在]

哈希表的时间复杂度最差,原因有两个:

  • 如果将太多元素散列到同一个键中:查看此键内部可能需要
    O(n)
    时间
  • 一旦一个哈希表通过了它的-它必须重新刷新[创建一个新的更大的表,并将每个元素重新插入表] 然而,它被称为平均和摊销情况,因为:

  • 如果您选择了一个好的散列函数,并且没有太大的负载平衡,那么将许多项散列到同一个键是非常罕见的
  • 再灰化操作,即
    O(n)
    ,最多可以发生在
    n/2
    ops之后,这些操作都是假定的
    O(1)
    :因此,当您对每个ops的平均时间求和时,您得到:
    (n*O(1)+O(n))/n)=O(1)
  • 注意:由于重灰化问题(实时应用程序和需要低容量的应用程序),不应使用哈希表作为其数据结构

    编辑:注释哈希表的其他问题:

    另一个在大型哈希表中可能会出现性能损失的问题是由于缓存性能。哈希表的缓存性能不好,因此对于大型收集,访问时间可能会更长,因为需要将表的相关部分从内存重新加载回缓存。

    一些哈希表bles()保证了O(1)查找

    如果你能实现它使它成为O(1),为什么你要实现它,使它成为O(n)?我说的是最坏的情况case@JigarJoshi:你能在最坏的情况下得到O(n)吗运行时?返回单个数字的哈希函数,因此所有条目都将在同一个bucketOh中-我只是在看最坏的情况。因此,要清楚,当人们说O(1)时,他们只是指平均情况?@user1136342:编辑答案以试图澄清这一点。通常,对于哈希表来说,
    table_size/8一个完美的值是O(1)查找,但在设计表时,您必须知道数据是什么。O(n)是最坏的情况,O(1)是平均情况。在最坏的情况下,您可以插入n个元素,所有元素都散列到同一个bucket中。然后,对于此数据集,删除和搜索也将是O(n).相关:谢谢-我想我明白了。所以,如果在考试或面试期间要求我提出一个在O(1)中执行查找的数据结构,你知道包括哈希表是否合适吗?@user1136342:这取决于你需要的是最坏情况还是平均情况。对于平均情况,哈希表是
    O(1)
    。如果您需要最坏情况-哈希表是不够的。Wikipedia通过在每个bucket中使用更复杂的数据结构,将最坏情况从
    O(n)
    描述为
    O(log n)
    。(我想如果哈希表已经使用了一个好的加密哈希,这可能会被认为是杀伤力过大,甚至可以防止来自攻击者的冲突。)@joey将排序数组作为辅助数据结构进行旋转并不难,然后您确实可以保证O(log(n))查找的最坏情况。还有其他哈希表可以保证O(log(n))最坏情况查找,例如,通过使用大小为n²的完美哈希表作为辅助数据结构,您甚至可以保证O(1)最坏情况查找。很抱歉