Jump to content
 







Main menu
   


Navigation  



Main page
Contents
Current events
Random article
About Wikipedia
Contact us
Donate
 




Contribute  



Help
Learn to edit
Community portal
Recent changes
Upload file
 








Search  

































Create account

Log in
 









Create account
 Log in
 




Pages for logged out editors learn more  



Contributions
Talk
 



















Contents

   



(Top)
 


1 Description  





2 Operations  



2.1  Insertion  





2.2  Search  



2.2.1  Pseudocode  







2.3  Deletion  





2.4  Traversal  





2.5  Partial-match searching  





2.6  Near-neighbor searching  







3 Running time  





4 Comparison to other data structures  



4.1  Tries  





4.2  Hash maps  





4.3  DAFSAs (deterministic acyclic finite state automaton)  







5 Uses  





6 See also  





7 References  





8 External links  














Ternary search tree






فارسی
Français

Polski
Português
Српски / srpski

Українська

 

Edit links
 









Article
Talk
 

















Read
Edit
View history
 








Tools
   


Actions  



Read
Edit
View history
 




General  



What links here
Related changes
Upload file
Special pages
Permanent link
Page information
Cite this page
Get shortened URL
Download QR code
Wikidata item
 




Print/export  



Download as PDF
Printable version
 
















Appearance
   

 






From Wikipedia, the free encyclopedia
 


Ternary Search Tree (TST)
Typetree
Time complexityinbig O notation
Operation Average Worst case
Search O(log n) O(n)
Insert O(log n) O(n)
Delete O(log n) O(n)
Space complexity

Incomputer science, a ternary search tree is a type of trie (sometimes called a prefix tree) where nodes are arranged in a manner similar to a binary search tree, but with up to three children rather than the binary tree's limit of two. Like other prefix trees, a ternary search tree can be used as an associative map structure with the ability for incremental string search. However, ternary search trees are more space efficient compared to standard prefix trees, at the cost of speed. Common applications for ternary search trees include spell-checking and auto-completion.

Description

[edit]

Each node of a ternary search tree stores a single character, an object (or a pointer to an object depending on implementation), and pointers to its three children conventionally named equal kid, lo kid and hi kid, which can also be referred respectively as middle (child), lower (child) and higher (child).[1] A node may also have a pointer to its parent node as well as an indicator as to whether or not the node marks the end of a word.[2] The lo kid pointer must point to a node whose character value is less than the current node. The hi kid pointer must point to a node whose character is greater than the current node.[1] The equal kid points to the next character in the word. The figure below shows a ternary search tree with the strings "cute","cup","at","as","he","us" and "i":

          c
        / | \
       a  u  h
       |  |  | \
       t  t  e  u
     /  / |   / |
    s  p  e  i  s

As with other trie data structures, each node in a ternary search tree represents a prefix of the stored strings. All strings in the middle subtree of a node start with that prefix.

Operations

[edit]

Insertion

[edit]

Inserting a value into a ternary search can be defined recursively or iteratively much as lookups are defined. This recursive method is continually called on nodes of the tree given a key which gets progressively shorter by pruning characters off the front of the key. If this method reaches a node that has not been created, it creates the node and assigns it the character value of the first character in the key. Whether a new node is created or not, the method checks to see if the first character in the string is greater than or less than the character value in the node and makes a recursive call on the appropriate node as in the lookup operation. If, however, the key's first character is equal to the node's value then the insertion procedure is called on the equal kid and the key's first character is pruned away.[1] Like binary search trees and other data structures, ternary search trees can become degenerate depending on the order of the keys.[3][self-published source?] Inserting keys in alphabetical order is one way to attain the worst possible degenerate tree.[1] Inserting the keys in random order often produces a well-balanced tree.[1]

function insertion(string key) is
 node p := root 
    //initialized to be equal in case root is null
 node last := root
 int idx := 0
 while p is not null do
        //recurse on proper subtree
  if key[idx] < p.splitchar then
   last := p
   p := p.left
  else if key[idx] > p.splitchar then
   last := p
   p := p.right
  else:
            // key is already in our Tree
   if idx == length(key) then
    return 
            //trim character from our key 
   idx := idx+1
   last := p
   p := p.mid
 p := node()
    //add p in as a child of the last non-null node (or root if root is null)
    if root == null then
        root := p
 else if last.splitchar < key[idx] then
  last.right := p
 else if last.splitchar > key[idx] then
  last.left := p
 else 
  last.mid := p
 p.splitchar := key[idx]
 idx := idx+1
    // Insert remainder of key
 while idx < length(key) do
  p.mid := node()
        p.mid.splitchar := key[idx]
  idx += 1
[edit]

To look up a particular node or the data associated with a node, a string key is needed. A lookup procedure begins by checking the root node of the tree and determining which of the following conditions has occurred. If the first character of the string is less than the character in the root node, a recursive lookup can be called on the tree whose root is the lo kid of the current root. Similarly, if the first character is greater than the current node in the tree, then a recursive call can be made to the tree whose root is the hi kid of the current node.[1] As a final case, if the first character of the string is equal to the character of the current node then the function returns the node if there are no more characters in the key. If there are more characters in the key then the first character of the key must be removed and a recursive call is made given the equal kid node and the modified key.[1] This can also be written in a non-recursive way by using a pointer to the current node and a pointer to the current character of the key.[1]

Pseudocode

[edit]
 function search(string query) is
     if is_empty(query) then
         return false
 
     node p := root
     int idx := 0
 
     while p is not null do
         if query[idx] < p.splitchar then
             p := p.left
         else if query[idx] > p.splitchar then
             p := p.right;
         else
             if idx = length(query) then
                 return true
             idx := idx + 1
             p := p.mid
 
     return false

Deletion

[edit]

The delete operation consists of searching for a key string in the search tree and finding a node, called firstMid in the below pseudocode, such that the path from the middle child of firstMid to the end of the search path for the key string has no left or right children. This would represent a unique suffix in the ternary tree corresponding to the key string. If there is no such path, this means that the key string is either fully contained as a prefix of another string, or is not in the search tree. Many implementations make use of an end of string character to ensure only the latter case occurs. The path is then deleted from firstMid.mid to the end of the search path. In the case that firstMid is the root, the key string must have been the last string in the tree, and thus the root is set to null after the deletion.

 function delete(string key) is
     if is_empty(key) then
         return 
 
     node p := root
     int idx := 0

   node firstMid := null
     while p is not null do
         if key[idx] < p.splitchar then
             firstMid := null
             p := p.left
         else if key[idx] > p.splitchar then
             firstMid := null
             p := p.right
         else
             firstMid := p
             while p is not null and key[idx] == p.splitchar do
              idx := idx + 1
              p := p.mid
             
     if firstMid == null then
         return  // No unique string suffix

     // At this point, firstMid points to the node before the strings unique suffix occurs
     node q := firstMid.mid 
     node p := q
     firstMid.mid := null // disconnect suffix from tree
     while q is not null do //walk down suffix path and delete nodes 
         p := q
         q := q.mid 
         delete(p)   // free memory associated with node p
     if firstMid == root then 
         delete(root)       //delete the entire tree
         root := null

Traversal

[edit]

[clarification needed][example needed]

Partial-match searching

[edit]

[clarification needed][example needed]

Near-neighbor searching

[edit]

[clarification needed][example needed]

Running time

[edit]

The running time of ternary search trees varies significantly with the input. Ternary search trees run best when given several similar strings, especially when those strings share a common prefix. Alternatively, ternary search trees are effective when storing a large number of relatively short strings (such as words in a dictionary).[1] Running times for ternary search trees are similar to binary search trees, in that they typically run in logarithmic time, but can run in linear time in the degenerate (worst) case. Further, the size of the strings must also be kept in mind when considering runtime. For example, in the search path for a string of length k, there will be k traversals down middle children in the tree, as well as a logarithmic number of traversals down left and right children in the tree. Thus, in a ternary search tree on a small number of very large strings the lengths of the strings can dominate the runtime.[4]

Time complexities for ternary search tree operations:[1]

Average-case running time Worst-case running time
Lookup O(log n + k) O(n + k)
Insertion O(log n + k) O(n + k)
Delete O(log n + k) O(n + k)

Comparison to other data structures

[edit]

Tries

[edit]

While being slower than other prefix trees, ternary search trees can be better suited for larger data sets due to their space-efficiency.[1]

Hash maps

[edit]

Hashtables can also be used in place of ternary search trees for mapping strings to values. However, hash maps also frequently use more memory than ternary search trees (but not as much as tries). Additionally, hash maps are typically slower at reporting a string that is not in the same data structure, because it must compare the entire string rather than just the first few characters. There is some evidence that shows ternary search trees running faster than hash maps.[1] Additionally, hash maps do not allow for many of the uses of ternary search trees, such as near-neighbor lookups.

[edit]

If storing dictionary words is all that is required (i.e., storage of information auxiliary to each word is not required), a minimal deterministic acyclic finite state automaton (DAFSA) would use less space than a trie or a ternary search tree. This is because a DAFSA can compress identical branches from the trie which correspond to the same suffixes (or parts) of different words being stored.

Uses

[edit]

Ternary search trees can be used to solve many problems in which a large number of strings must be stored and retrieved in an arbitrary order. Some of the most common or most useful of these are below:

See also

[edit]

References

[edit]
  1. ^ a b c d e f g h i j k l m n "Ternary Search Trees". Dr. Dobb's.
  • ^ a b Ostrovsky, Igor. "Efficient auto-complete with a ternary search tree".
  • ^ a b Wrobel, Lukasz. "Ternary Search Tree".
  • ^ Bentley, Jon; Sedgewick, Bob. "Ternary Search Tree".
  • ^ a b c Flint, Wally (February 16, 2001). "Plant your data in a ternary search tree". JavaWorld. Retrieved 2020-07-19.
  • [edit]
    Retrieved from "https://en.wikipedia.org/w/index.php?title=Ternary_search_tree&oldid=1080145790"

    Categories: 
    Trees (data structures)
    Search algorithms
    Hidden categories: 
    Articles needing expert attention from September 2016
    All articles needing expert attention
    Computing articles needing expert attention
    All articles with self-published sources
    Articles with self-published sources from May 2015
    Wikipedia articles needing clarification from September 2016
    All articles needing examples
    Articles needing examples from September 2016
     



    This page was last edited on 30 March 2022, at 15:17 (UTC).

    Text is available under the Creative Commons Attribution-ShareAlike License 4.0; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization.



    Privacy policy

    About Wikipedia

    Disclaimers

    Contact Wikipedia

    Code of Conduct

    Developers

    Statistics

    Cookie statement

    Mobile view



    Wikimedia Foundation
    Powered by MediaWiki