我对哈希表的时间复杂度感到困惑。
我了解到,由于调整大小,插入,搜索等将分摊O(1)时间,在计算哈希码后数组访问的时间是恒定的,因此我们始终可以将哈希表的负载因子保持为a常量值,并且良好的哈希码使我们的冲突降至最低。
但是,我的问题是关于hashCode()本身的运行时的。
我的理解是insert(),get()等首先依赖于计算哈希码,然后通常将给定项存储在索引i = hashCode()%buckets.length
上。这似乎与哈希表的摊销O(1)性能冲突,因为O(1)性能似乎假定计算哈希码是恒定时间。
但是,据我了解,对于许多递归对象(例如链表),我们以递归方式计算哈希码(为简单起见,我省略了基本情况):
hashcode():
return this.item.hashCode() + 31 * this.next.hashCode()
这是否意味着hashCode()具有O(N)运行时,因此哈希表的insert()将具有O(N)运行时?
如果是这种情况,那么哈希表的insert()对于具有慢hashCode()函数的插入项是否会很糟糕?即使对于插入字符串之类的东西,这也不意味着insert()会是O(N),其中N是字符串的长度,因为我们会根据字符串中的每个字符来计算哈希码?
我已经看到哈希码以前已经被缓存了,但是缓存仅发生在对象的特定实例上,这意味着我们需要多次插入对象的同一实例才能使缓存生效,但这并没有。在实际情况下似乎没有什么帮助。
如果我的说法是正确的,那么这是否意味着对于某些顺序数据(例如字符串),Trie会具有更好的性能,因为它的insert()和get()将是O(L)最坏的情况, L是要插入的项目/序列的长度-这是Tries的重点吗?