三元树与哈希表

时间:2009-05-05 07:27:04

标签: algorithm hashtable ternary-search-tree

我需要知道ternary tree是否优于hash table

我在对another question I had的回复中遇到了这个问题,有人说三元树通常比哈希表更快。我发现很难相信,所以我决定研究一下。

This one website from Princeton似乎是信仰的源泉。我看了一下算法,它被描述为O(log n + k),其中n是存储的字数,k是密钥的长度。

在我看来,如果你经常搜索尚未存储的元素,那么这种方法可能更快。困扰我的另一件事是,trie的非连续爬行会导致你击中已经被换掉的页面,但是这是否是一个主要的影响只能通过基准来看。

现在我知道两者都有利有弊,如果是的话,我想知道它们是什么。基准测试也很有帮助。

5 个答案:

答案 0 :(得分:7)

以下是我从您提供的Princeton链接中可以找到的Dr. Dobbs Article收集的内容:

  1. 在某些搜索问题上,三元搜索树比哈希表快10%。它们有时会变慢 - 主要取决于使用的机器。
  2. TRT是由计算机科学的两位最优秀人才调整的自定义数据结构 - Jon Bentley和Robert Sedgewick都撰写了good textbooks,并完成了实际编程的一部分。哈希表被认为是普通的。
  3. 正如Hao Wooi Lin所说,所涉及的常数非常重要。
  4. 总的来说,这取决于您正在解决的问题。在许多编程语言中,更快的开发时间和几乎无处不在的哈希表支持通常比运行时间提高10%更重要。

答案 1 :(得分:4)

回答这个问题的唯一方法是凭经验。答案取决于您的实现细节,您执行的搜索类型,您拥有的硬件以及您正在使用的编译器。您可以从普林斯顿复制C代码。如果你想尝试一种函数式语言,标准ML有哈希表(看SML/NJ),这里有一些用于三元搜索树的ML:

type key = Key.ord_key
type item = Key.ord_key list

datatype set = NODE of { key : key, lt : set, eq : set, gt : set }
             | LEAF

val empty = LEAF

fun member (_, LEAF) = false
  | member (h::t, NODE {key, lt, eq, gt}) =
      (case Key.compare (h, key)
         of EQUAL   => member(t, eq)
          | LESS    => member(h::t, lt)
          | GREATER => member(h::t, gt))
  | member ([], NODE {key, lt, eq, gt}) =
      (case Key.compare (Key.sentinel, key)
         of EQUAL   => true
          | LESS    => member([], lt)
          | GREATER => member([], gt))

exception AlreadyPresent

fun insert(h::t, LEAF) =
      NODE { key = h, eq = insert(t, LEAF), lt = LEAF, gt = LEAF }
  | insert([], LEAF) =
      NODE { key = Key.sentinel, eq = LEAF, lt = LEAF, gt = LEAF }
  | insert(h::t, NODE {key, lt, eq, gt}) =
      (case Key.compare (h, key)
         of EQUAL   => NODE {key = key, lt = lt, gt = gt, eq = insert(t, eq)}
          | LESS    => NODE {key = key, lt = insert(h::t, lt), gt = gt, eq = eq}
          | GREATER => NODE {key = key, lt = lt, gt = insert(h::t, gt), eq = eq})
  | insert([], NODE {key, lt, eq, gt}) =
      (case Key.compare (Key.sentinel, key)
         of EQUAL   => raise AlreadyPresent
          | LESS    => NODE {key = key, lt = insert([], lt), gt = gt, eq = eq}
          | GREATER => NODE {key = key, lt = lt, gt = insert([], gt), eq = eq})

fun add(l, n) = insert(l, n) handle AlreadyPresent => n

答案 2 :(得分:1)

log(n)缓慢增长,因此在考虑常数因素时,它往往需要大量数据才能比O(1)算法慢。

答案 3 :(得分:0)

这对我来说也很有趣。但是从我阅读的wiki中,它声称三元树在大多数搜索问题上都更快。这并不奇怪,因为即使哈希表具有O(1)查找,您仍然需要时间进行哈希处理。所以它不是真的O(1)而是更像O(k),其中k不依赖于N(数据结构中的项目数)。这可能会给人留下Hash Table更快的印象。但是,如果你正在处理一个大型结构,那么k会很快加起来,并且哈希表的搜索速度会慢于三元树。

答案 4 :(得分:0)

您可以查看tstdb:http://code.google.com/p/tstdb/

这个kv商店基于三元搜索树,它与Memcached兼容。此外,tstdb支持三元搜索树促进的前缀搜索和范围查询。