在计算机科学中,据说哈希表的插入,删除和搜索操作具有O(1)的复杂度,这是最好的。所以,我想知道,为什么我们需要使用其他数据结构,因为散列操作如此之快?为什么我们不能简单地使用哈希/哈希表来处理所有事情?
答案 0 :(得分:29)
散列表平均来说,插入,检索和删除的时间复杂度非常高。但是:
Big-O复杂性并非一切。 常数因子也非常重要。您可以使用哈希表代替数组,将数组索引作为哈希键。在任何一种情况下,检索项目的时间复杂度是O(1)。但是,与数组相反,哈希表的常数因子 way 更高。
内存消耗可能会高得多。如果使用哈希表替换数组,这肯定是正确的。 (当然,如果数组是稀疏的,那么哈希表可能会占用更少的内存。)
哈希表无法有效支持某些操作,例如迭代其键在一定范围内的所有元素,查找具有最大键或最小键的元素,等等。 / p>
除此之外,你做仍然有一个好点。 Hashtables具有非常广泛的合适用例。这就是为什么它们是某些脚本语言中的主要内置数据结构,如Lua。
答案 1 :(得分:5)
您可以使用Hash来搜索元素,但是您不能使用它来执行快速查找最大数字之类的事情,您应该使用数据结构来处理指定的问题。哈希无法解决所有问题。
答案 2 :(得分:3)
HashTable
并非所有人都回答。如果你的哈希函数没有很好地分发你的密钥,那么在最坏的情况下,hashMap
可能变为linkedList
,在最坏的情况下,插入,删除,搜索将采用O(N)
。
HashMap
占用大量内存,因此在某些用例中,您的内存过于珍贵而不是时间复杂度,那么HashMap
可能不是最佳选择。
HashMap
不是范围查询或前缀查询的答案。这就是为什么大多数数据库供应商确实通过Btree
实现索引而不是仅通过散列进行范围或前缀查询。
HashTable
通常表现出较差的引用位置,即要访问的数据在内存中随机分布。
对于某些字符串处理应用程序,例如拼写检查,哈希表的效率可能低于尝试,有限自动机或Judy数组。此外,如果每个键由足够少的位表示,则可以使用该键直接作为值数组的索引而不是哈希表。请注意,在这种情况下没有碰撞。
答案 3 :(得分:2)
还应指出Web上哈希表的潜在安全问题。如果有人知道散列函数,那么该人可以通过创建大量具有相同散列码的项来执行拒绝服务攻击。
答案 4 :(得分:0)
答案 5 :(得分:0)
我不明白,枚举/符号键不够浪费? ;) 仅使用原始字符串指针作为键怎么样?我一定忽略了散列的一些明显优势……但现在想想,它越来越没有意义。
无论如何,这只是当地的代表,对吗?我的意思是,我可以在任何地方共享数据... API、IPC 或 RPC - 但不确定这些散列键有多大帮助,除非也嵌入了完整的字符串。
这意味着您只是为了自己的娱乐而花费了大量时间来回散列字符串。