Trie | (Insert and Search)

25 Jun, 2022
Trie is an efficient information retrieval data structure. Using Trie, search complexities can be brought to optimal limit (key length). If we store keys in a binary search tree, a well balanced BST will need time proportional to M * log N, where M is the maximum string length and N is the number of keys in the tree. Using Trie, we can search the key in O(M) time. However, the penalty is on Trie storage requirements (Please refer to Applications of Trie for more details) 
Every node of Trie consists of multiple branches. Each branch represents a possible character of keys. We need to mark the last node of every key as the end of the word node. A Trie node field isEndOfWord is used to distinguish the node as the end of the word node. A simple structure to represent nodes of the English alphabet can be as follows, // Trie node struct TrieNode {      struct TrieNode *children[ALPHABET_SIZE];     // isEndOfWord is true if the node      // represents end of a word      bool isEndOfWord; }; Inserting a key into Trie is a simple approach. Every character of the input key is inserted as an individual Trie node. Note that the children is an array of pointers (or references) to next level trie nodes. The key character acts as an index to the array children. If the input key is new or an extension of the existing key, we need to construct non-existing nodes of the key, and mark the end of the word for the last node. If the input key is a prefix of the existing key in Trie, we simply mark the last node of the key as the end of a word. The key length determines Trie depth.  
Searching for a key is similar to an insert operation, however, we only compare the characters and move down. The search can terminate due to the end of a string or lack of key in the trie. In the former case, if the isEndofWord field of the last node is true, then the key exists in the trie. In the second case, the search terminates without examining all the characters of the key, since the key is not present in the trie.The following picture explains the construction of trie using keys given in the example below,  
                       root
                    /   \    \
                    t   a     b
                    |   |     |
                    h   n     y
                    |   |  \  |
                    e   s  y  e
                 /  |   |
                 i  r   w
                 |  |   |
                 r  e   e
                        |
                        r
In the picture, every character is of type trie_node_t. For example, the root is of type trie_node_t, and it’s children a, b and t are filled, all other nodes of root will be NULL. Similarly, “a” at the next level is having only one child (“n”), all other children are NULL. The leaf nodes are in blue. 
Chapters
descriptions off, selected
captions settings, opens captions settings dialog
captions off, selected
English
This is a modal window.
Beginning of dialog window. Escape will cancel and close the window.
End of dialog window.
Insert and search costs O(key_length), however, the memory requirements of Trie is O(ALPHABET_SIZE * key_length * N) where N is the number of keys in Trie. There are efficient representations of trie nodes (e.g. compressed trie, ternary search tree, etc.) to minimize the memory requirements of the trie. 
 
C++
C
Java
Python3
C#
Javascript
PHP
// C++ implementation of search and insert// operations on Trie#include <bits/stdc++.h>using namespace std;  const int ALPHABET_SIZE = 26;  // trie nodestruct TrieNode{    struct TrieNode *children[ALPHABET_SIZE];      // isEndOfWord is true if the node represents    // end of a word    bool isEndOfWord;};  // Returns new trie node (initialized to NULLs)struct TrieNode *getNode(void){    struct TrieNode *pNode =  new TrieNode;      pNode->isEndOfWord = false;      for (int i = 0; i < ALPHABET_SIZE; i++)        pNode->children[i] = NULL;      return pNode;}  // If not present, inserts key into trie// If the key is prefix of trie node, just// marks leaf nodevoid insert(struct TrieNode *root, string key){    struct TrieNode *pCrawl = root;      for (int i = 0; i < key.length(); i++)    {        int index = key[i] - 'a';        if (!pCrawl->children[index])            pCrawl->children[index] = getNode();          pCrawl = pCrawl->children[index];    }      // mark last node as leaf    pCrawl->isEndOfWord = true;}  // Returns true if key presents in trie, else// falsebool search(struct TrieNode *root, string key){    struct TrieNode *pCrawl = root;      for (int i = 0; i < key.length(); i++)    {        int index = key[i] - 'a';        if (!pCrawl->children[index])            return false;          pCrawl = pCrawl->children[index];    }      return (pCrawl->isEndOfWord);}  // Driverint main(){    // Input keys (use only 'a' through 'z'    // and lower case)    string keys[] = {"the", "a", "there",                    "answer", "any", "by",                     "bye", "their" };    int n = sizeof(keys)/sizeof(keys[0]);      struct TrieNode *root = getNode();      // Construct trie    for (int i = 0; i < n; i++)        insert(root, keys[i]);      // Search for different keys    search(root, "the")? cout << "Yes\n" :                         cout << "No\n";    search(root, "these")? cout << "Yes\n" :                           cout << "No\n";    search(root, "their")? cout << "Yes\n" :                         cout << "No\n";    search(root, "thaw")? cout << "Yes\n" :                           cout << "No\n";    return 0;}
// C implementation of search and insert operations// on Trie#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdbool.h>  #define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])  // Alphabet size (# of symbols)#define ALPHABET_SIZE (26)  // Converts key current character into index// use only 'a' through 'z' and lower case#define CHAR_TO_INDEX(c) ((int)c - (int)'a')  // trie nodestruct TrieNode{    struct TrieNode *children[ALPHABET_SIZE];      // isEndOfWord is true if the node represents    // end of a word    bool isEndOfWord;};  // Returns new trie node (initialized to NULLs)struct TrieNode *getNode(void){    struct TrieNode *pNode = NULL;      pNode = (struct TrieNode *)malloc(sizeof(struct TrieNode));      if (pNode)    {        int i;          pNode->isEndOfWord = false;          for (i = 0; i < ALPHABET_SIZE; i++)            pNode->children[i] = NULL;    }      return pNode;}  // If not present, inserts key into trie// If the key is prefix of trie node, just marks leaf nodevoid insert(struct TrieNode *root, const char *key){    int level;    int length = strlen(key);    int index;      struct TrieNode *pCrawl = root;      for (level = 0; level < length; level++)    {        index = CHAR_TO_INDEX(key[level]);        if (!pCrawl->children[index])            pCrawl->children[index] = getNode();          pCrawl = pCrawl->children[index];    }      // mark last node as leaf    pCrawl->isEndOfWord = true;}  // Returns true if key presents in trie, else falsebool search(struct TrieNode *root, const char *key){    int level;    int length = strlen(key);    int index;    struct TrieNode *pCrawl = root;      for (level = 0; level < length; level++)    {        index = CHAR_TO_INDEX(key[level]);          if (!pCrawl->children[index])            return false;          pCrawl = pCrawl->children[index];    }      return (pCrawl->isEndOfWord);}  // Driverint main(){    // Input keys (use only 'a' through 'z' and lower case)    char keys[][8] = {"the", "a", "there", "answer", "any",                     "by", "bye", "their"};      char output[][32] = {"Not present in trie", "Present in trie"};        struct TrieNode *root = getNode();      // Construct trie    int i;    for (i = 0; i < ARRAY_SIZE(keys); i++)        insert(root, keys[i]);      // Search for different keys    printf("%s --- %s\n", "the", output[search(root, "the")] );    printf("%s --- %s\n", "these", output[search(root, "these")] );    printf("%s --- %s\n", "their", output[search(root, "their")] );    printf("%s --- %s\n", "thaw", output[search(root, "thaw")] );      return 0;}
// Java implementation of search and insert operations// on Triepublic class Trie {          // Alphabet size (# of symbols)    static final int ALPHABET_SIZE = 26;          // trie node    static class TrieNode    {        TrieNode[] children = new TrieNode[ALPHABET_SIZE];               // isEndOfWord is true if the node represents        // end of a word        boolean isEndOfWord;                  TrieNode(){            isEndOfWord = false;            for (int i = 0; i < ALPHABET_SIZE; i++)                children[i] = null;        }    };           static TrieNode root;           // If not present, inserts key into trie    // If the key is prefix of trie node,     // just marks leaf node    static void insert(String key)    {        int level;        int length = key.length();        int index;               TrieNode pCrawl = root;               for (level = 0; level < length; level++)        {            index = key.charAt(level) - 'a';            if (pCrawl.children[index] == null)                pCrawl.children[index] = new TrieNode();                   pCrawl = pCrawl.children[index];        }               // mark last node as leaf        pCrawl.isEndOfWord = true;    }           // Returns true if key presents in trie, else false    static boolean search(String key)    {        int level;        int length = key.length();        int index;        TrieNode pCrawl = root;               for (level = 0; level < length; level++)        {            index = key.charAt(level) - 'a';                   if (pCrawl.children[index] == null)                return false;                   pCrawl = pCrawl.children[index];        }               return (pCrawl.isEndOfWord);    }           // Driver    public static void main(String args[])    {        // Input keys (use only 'a' through 'z' and lower case)        String keys[] = {"the", "a", "there", "answer", "any",                         "by", "bye", "their"};               String output[] = {"Not present in trie", "Present in trie"};                      root = new TrieNode();               // Construct trie        int i;        for (i = 0; i < keys.length ; i++)            insert(keys[i]);               // Search for different keys        if(search("the") == true)            System.out.println("the --- " + output[1]);        else System.out.println("the --- " + output[0]);                  if(search("these") == true)            System.out.println("these --- " + output[1]);        else System.out.println("these --- " + output[0]);                  if(search("their") == true)            System.out.println("their --- " + output[1]);        else System.out.println("their --- " + output[0]);                  if(search("thaw") == true)            System.out.println("thaw --- " + output[1]);        else System.out.println("thaw --- " + output[0]);             }}// This code is contributed by Sumit Ghosh
# Python program for insert and search# operation in a Trie  class TrieNode:          # Trie node class    def __init__(self):        self.children = [None]*26          # isEndOfWord is True if node represent the end of the word        self.isEndOfWord = False  class Trie:          # Trie data structure class    def __init__(self):        self.root = self.getNode()      def getNode(self):              # Returns new trie node (initialized to NULLs)        return TrieNode()      def _charToIndex(self,ch):                  # private helper function        # Converts key current character into index        # use only 'a' through 'z' and lower case                  return ord(ch)-ord('a')        def insert(self,key):                  # If not present, inserts key into trie        # If the key is prefix of trie node,         # just marks leaf node        pCrawl = self.root        length = len(key)        for level in range(length):            index = self._charToIndex(key[level])              # if current character is not present            if not pCrawl.children[index]:                pCrawl.children[index] = self.getNode()            pCrawl = pCrawl.children[index]          # mark last node as leaf        pCrawl.isEndOfWord = True      def search(self, key):                  # Search key in the trie        # Returns true if key presents         # in trie, else false        pCrawl = self.root        length = len(key)        for level in range(length):            index = self._charToIndex(key[level])            if not pCrawl.children[index]:                return False            pCrawl = pCrawl.children[index]          return pCrawl.isEndOfWord  # driver functiondef main():      # Input keys (use only 'a' through 'z' and lower case)    keys = ["the","a","there","anaswe","any",            "by","their"]    output = ["Not present in trie",              "Present in trie"]      # Trie object    t = Trie()      # Construct trie    for key in keys:        t.insert(key)      # Search for different keys    print("{} ---- {}".format("the",output[t.search("the")]))    print("{} ---- {}".format("these",output[t.search("these")]))    print("{} ---- {}".format("their",output[t.search("their")]))    print("{} ---- {}".format("thaw",output[t.search("thaw")]))  if __name__ == '__main__':    main()  # This code is contributed by Atul Kumar (www.facebook.com/atul.kr.007)
// C# implementation of search and // insert operations on Trieusing System;      public class Trie {          // Alphabet size (# of symbols)    static readonly int ALPHABET_SIZE = 26;          // trie node    class TrieNode    {        public TrieNode[] children = new TrieNode[ALPHABET_SIZE];              // isEndOfWord is true if the node represents        // end of a word        public bool isEndOfWord;                  public TrieNode()        {            isEndOfWord = false;            for (int i = 0; i < ALPHABET_SIZE; i++)                children[i] = null;        }    };          static TrieNode root;           // If not present, inserts key into trie    // If the key is prefix of trie node,     // just marks leaf node    static void insert(String key)    {        int level;        int length = key.Length;        int index;              TrieNode pCrawl = root;              for (level = 0; level < length; level++)        {            index = key[level] - 'a';            if (pCrawl.children[index] == null)                pCrawl.children[index] = new TrieNode();                  pCrawl = pCrawl.children[index];        }              // mark last node as leaf        pCrawl.isEndOfWord = true;    }          // Returns true if key     // presents in trie, else false    static bool search(String key)    {        int level;        int length = key.Length;        int index;        TrieNode pCrawl = root;              for (level = 0; level < length; level++)        {            index = key[level] - 'a';                  if (pCrawl.children[index] == null)                return false;                  pCrawl = pCrawl.children[index];        }              return (pCrawl.isEndOfWord);    }          // Driver    public static void Main()    {        // Input keys (use only 'a'         // through 'z' and lower case)        String []keys = {"the", "a", "there", "answer",                         "any", "by", "bye", "their"};              String []output = {"Not present in trie", "Present in trie"};                    root = new TrieNode();              // Construct trie        int i;        for (i = 0; i < keys.Length ; i++)            insert(keys[i]);              // Search for different keys        if(search("the") == true)            Console.WriteLine("the --- " + output[1]);        else Console.WriteLine("the --- " + output[0]);                  if(search("these") == true)            Console.WriteLine("these --- " + output[1]);        else Console.WriteLine("these --- " + output[0]);                  if(search("their") == true)            Console.WriteLine("their --- " + output[1]);        else Console.WriteLine("their --- " + output[0]);                  if(search("thaw") == true)            Console.WriteLine("thaw --- " + output[1]);        else Console.WriteLine("thaw --- " + output[0]);              }}  /* This code contributed by PrinciRaj1992 */
<script>// Javascript implementation of search and insert operations// on Trie  // Alphabet size (# of symbols)let ALPHABET_SIZE = 26;  // trie nodeclass TrieNode{    constructor()    {        this.isEndOfWord = false;        this.children = new Array(ALPHABET_SIZE);        for (let i = 0; i < ALPHABET_SIZE; i++)            this.children[i] = null;    }}  let root;  // If not present, inserts key into trie    // If the key is prefix of trie node,    // just marks leaf nodefunction insert(key){    let level;        let length = key.length;        let index;                let pCrawl = root;                for (level = 0; level < length; level++)        {            index = key[level].charCodeAt(0) - 'a'.charCodeAt(0);            if (pCrawl.children[index] == null)                pCrawl.children[index] = new TrieNode();                    pCrawl = pCrawl.children[index];        }                // mark last node as leaf        pCrawl.isEndOfWord = true;}  // Returns true if key presents in trie, else falsefunction search(key){    let level;        let length = key.length;        let index;        let pCrawl = root;                for (level = 0; level < length; level++)        {            index = key[level].charCodeAt(0) - 'a'.charCodeAt(0);                    if (pCrawl.children[index] == null)                return false;                    pCrawl = pCrawl.children[index];        }                return (pCrawl.isEndOfWord);}  // Driver    // Input keys (use only 'a' through 'z' and lower case)let keys = ["the", "a", "there", "answer", "any",                 "by", "bye", "their"];  let output = ["Not present in trie", "Present in trie"];    root = new TrieNode();  // Construct trielet i;for (i = 0; i < keys.length ; i++)    insert(keys[i]);  // Search for different keysif(search("the") == true)    document.write("the --- " + output[1]+"<br>");else     document.write("the --- " + output[0]+"<br>");  if(search("these") == true)    document.write("these --- " + output[1]+"<br>");else    document.write("these --- " + output[0]+"<br>");  if(search("their") == true)    document.write("their --- " + output[1]+"<br>");else    document.write("their --- " + output[0]+"<br>");  if(search("thaw") == true)    document.write("thaw --- " + output[1]+"<br>");else    document.write("thaw --- " + output[0]+"<br>");    // This code is contributed by patel2127</script>
<?php# PHP program for insert and search operation in a Trie# Trie node classclass TrieNode {    public $isEnd = false;    public $children = [];}  class Trie {    # Trie data structure class    public $node = null;      //Initializing trie    public function __construct()     {        $this->node = new TrieNode();    }        // Inserts a word into the trie.      public function insert($word)     {        $count = strlen($word);        $node = $this->node;        for ($i = 0; $i < $count; $i++) {            $char = $word[$i];            if (array_key_exists($char, $node->children)) {                $node = $node->children[$char];                continue;            }            $node->children[$char] = new TrieNode();            $node = $node->children[$char];        }        $node->isEnd = true;    }        // Returns if the word is in the trie.           public function search($word): bool    {        $count = strlen($word);        $node = $this->node;        for ($i = 0; $i < $count; $i++) {            $char = $word[$i];            if (!array_key_exists($char, $node->children)) {                return false;            }            $node = $node->children[$char];        }          return $node->isEnd;    } }    $keys = array("the","a","there","answer","any","by","their");      # Trie object    $t = new Trie();      # Constructing trie    foreach ($keys as $key) {        $t->insert($key);    }       # Searching different words   print ($t->search("the")==1)?("Yes"):("No");   echo(' ');   print ($t->search("this")==1)?("Yes"):("No");   echo(' ');   print ($t->search("they")==1)?("Yes"):("No");   echo(' ');   print ($t->search("thaw")==1)?("Yes"):("No");  # This code is contributed by Sajal Aggarwal.    ?>
Output :
the --- Present in trie
these --- Not present in trie
their --- Present in trie
thaw --- Not present in trie
 
NOTE : In video, isEndOfWord is referred as isLeaf.Related Articles:  
Trie Delete
Displaying content of Trie
Applications of Trie
Auto-complete feature using Trie
Minimum Word Break
Sorting array of strings (or words) using Trie
Pattern Searching using a Trie of all Suffixes
Practice Problems :  
Trie Search and InsertTrie DeleteUnique rows in a binary matrixCount of distinct substringsWord Boggle
Trie Search and Insert
Trie Delete
Unique rows in a binary matrix
Count of distinct substrings
Word Boggle
Recent Articles on TrieThis article is contributed by Venki. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
 
princiraj1992
jarretchng02
jeetkaria
patel2127
amartyaghoshgfg
kiriti93
aggarwalsajal19
Amazon
D-E-Shaw
FactSet
Trie
Advanced Data Structure
Amazon
D-E-Shaw
FactSet
Trie
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
AVL Tree | Set 1 (Insertion)
LRU Cache Implementation
Introduction of B-Tree
Agents in Artificial Intelligence
Red-Black Tree | Set 1 (Introduction)
Decision Tree Introduction with example
Segment Tree | Set 1 (Sum of given range)
AVL Tree | Set 2 (Deletion)
Disjoint Set Data Structures
Difference between B tree and B+ tree