I need to know if a ternary tree is better than a hash table.
I came across this question in a reply to another question I had where someone said that ternary trees are often faster than hash tables. I found that hard to believe, so I decided to research a little into it.
This one website from Princeton appears to be the source of the belief. I took a look at algorithm which is described to be O(log n + k) where n is the number of words stored, and k is the length of the key.
It seems to me that the only way this could be faster is if you are often searching for elements that are not already stored. Another thing that bothers me, is that the non-continuous crawling of a trie would tend to cause you to hit pages that have been swapped out, but whether this is a major effect could only be seen through benchmarks.
Now I know that there are probably pros and cons to both of them, and if so, I want to know what they are. Benchmarks are also helpful.
Binary Search Trees are generally memory-efficient since they do not reserve more memory than they need to. On the other hand, Hash tables can be a bit more demanding if we don't know the exact number of elements we want to store.
The trie solution is more flexible to support more applications, such as auto-complete. Also, we can easily print all the words in the dictionary in alphabetic order with a trie. Therefore, if we want a full-text lookup application, the hash table is better as it has a faster lookup speed.
What is the advantage of a hash table over BST? Explanation: Hash table and BST both are examples of data structures. Hash table has an advantage that it has a better time complexity for performing insert, delete and search operations.
Used in spell checks: Ternary search trees can be used as a dictionary to store all the words. Once the word is typed in an editor, the word can be parallelly searched in the ternary search tree to check for correct spelling.
Here is what I gather from the Dr. Dobbs Article reachable from the Princeton link you gave:
The only way to answer this question is empirically. The answer depends on the details of your implementation, what kinds of searches you do, what hardware you have, and what compiler you're using. You can copy the C code from Princeton. If you want to try a functional language, Standard ML has hash tables (look at SML/NJ), and here is some ML for ternary search trees:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With