哈希表何时比搜索树更好用?
答案 0 :(得分:9)
取决于您想要对数据结构做什么。
Operation Hash table Search Tree
Search O(1) O(log(N))
Insert O(1) O(log(N))
Delete O(1) O(log(N))
Traversal O(N) O(N)
Min/Max-Key -hard- O(log(N))
Find-Next-Key -hard- O(1)
在Hashtable上插入,搜索取决于哈希的加载因子 桌子及其设计。设计糟糕的hastables可以进行O(N)搜索和插入。您的搜索树也是如此。
根据您的碰撞,在哈希表中删除可能很麻烦 解决方案状态。
遍历容器,查找最小/最大,查找下一个/上一个排序 由于排序,搜索树上的操作更好。
上述搜索树的所有估算均针对“平衡”搜索树。
答案 1 :(得分:1)
当平均访问和插入时间比最佳访问和插入时间更重要时。实际上我认为搜索树通常和哈希表一样好,因为即使理论上一个比一个log的大θ更好,log n也非常快,当你开始处理n的大值时对实际差异的影响缩小了。而且,一个人的大says并没有说明常数的价值。当然,这也适用于树的复杂性,但是实现中树的常数因子通常是非常低的数,而不是哈希表。
同样,我知道理论家会在这里不同意我,但这是我们在这里处理的计算机,并且对于计算机来说,对于计算机来说,任何重要的负担都必须是不切实际的大。如果n是万亿,那么n的对数是40,而今天的计算机可以相当快地执行40次迭代。对于n的日志增长到50,你已经有超过千万亿元素。
目前的C ++标准并没有在其容器中提供哈希表,而且我认为人们对它的好处已经十多年了。
答案 2 :(得分:1)
我对事物的看法:
Operation Hash table(1) SBB Search Tree(2)
.find(obj) -> obj O(1) O(1)*
.insert(obj) O(1) O(log(N))
.delete(obj) O(1) O(log(N))
.traverse / for x in... O(N) O(N)
.largerThan(obj) -> {objs} unsupported O(log(N))
\
union right O(1) + parent O(1)
.sorted() -> [obj] unsupported no need
\
already sorted so no need
to print out, .traverse() is O(N)
.findMin() -> obj unsupported** O(log(N)), maybe O(1)
\
descend from root, e.g.:
root.left.left.left...left -> O(log(N))
might be able to cache for O(1)
.findNext(obj) -> obj unsupported O(log(N))
\
first perform x=.find(obj) which is O(1)
then descend from that node, e.g.:
x.right.left.left...right -> O(log(N))
(1)http://en.wikipedia.org/wiki/Hash_table
(2)http://en.wikipedia.org/wiki/Self-balancing_binary_search_tree,例如http://en.wikipedia.org/wiki/Tango_tree或http://en.wikipedia.org/wiki/Splay_tree
(*)您可以将哈希表与搜索树结合使用来获取此值。没有渐近的速度或空间惩罚。否则,它是O(log(N))
。
(**)除非您永远不删除,否则只需缓存最小和最大的元素,并且O(1)
。
这些费用可以摊销。
<强>结论:强>
您希望在订购时使用树。
答案 3 :(得分:0)
在许多问题中,它取决于散列函数的价格。根据我的经验,对于合理的哈希函数,哈希值通常是平衡树的两倍,但它们肯定可能更慢。