Searching in Trie Data Structure

Search operation in Trie is performed in a similar way as the insertion operation but the only difference is that whenever we find that the array of pointers in curr node does not point to the current character of the word then return false instead of creating a new node for that current character of the word. 

This operation is used to search whether a string is present in the Trie data structure or not. There are two search approaches in the Trie data structure.

  1. Find whether the given word exists in Trie.
  2. Find whether any word that starts with the given prefix exists in Trie.

There is a similar search pattern in both approaches. The first step in searching a given word in Trie is to convert the word to characters and then compare every character with the trie node from the root node. If the current character is present in the node, move forward to its children. Repeat this process until all characters are found.

2.1 Searching Prefix in Trie Data Structure:

Search for the prefix “an” in the Trie Data Structure.

Search for the prefix “an” in Trie

Implementation of Prefix Search in Trie data structure:

C++
bool isPrefixExist(TrieNode* root, string& key)
{
    // Initialize the currentNode pointer
    // with the root node
    TrieNode* currentNode = root;

    // Iterate across the length of the string
    for (auto c : key) {

        // Check if the node exist for the current
        // character in the Trie.
        if (currentNode->childNode[c - 'a'] == NULL) {
          
            // Given word as a prefix does not exist in Trie
            return false;
        }

        // Move the currentNode pointer to the already 
        // existing node for current character.
        currentNode = currentNode->childNode[c - 'a'];
    }
 
      // Prefix exist in the Trie
    return true;
}
Java
public boolean isPrefixExist(TrieNode root, String key) {
    // Initialize the currentNode pointer
    // with the root node
    TrieNode currentNode = root;

    // Iterate across the length of the string
    for (char c : key.toCharArray()) {

        // Check if the node exist for the current
        // character in the Trie.
        if (currentNode.childNode[c - 'a'] == null) {
          
            // Given word as a prefix does not exist in Trie
            return false;
        }

        // Move the currentNode pointer to the already 
        // existing node for current character.
        currentNode = currentNode.childNode[c - 'a'];
    }
 
      // Prefix exist in the Trie
    return true;
}
Python3
def is_prefix_exist(root, key):
    # Initialize the currentNode pointer
    # with the root node
    current_node = root

    # Iterate across the length of the string
    for c in key:
        # Check if the node exist for the current
        # character in the Trie.
        if current_node.child_node[ord(c) - ord('a')] is None:
            # Given word as a prefix does not exist in Trie
            return False

        # Move the currentNode pointer to the already 
        # existing node for current character.
        current_node = current_node.child_node[ord(c) - ord('a')]

    # Prefix exist in the Trie
    return True
C#
public bool isPrefixExist(TrieNode root, string key)
{
    // Initialize the currentNode pointer
    // with the root node
    TrieNode currentNode = root;

    // Iterate across the length of the string
    foreach (char c in key)
    {

        // Check if the node exist for the current
        // character in the Trie.
        if (currentNode.childNode[c - 'a'] == null)
        {

            // Given word as a prefix does not exist in Trie
            return false;
        }

        // Move the currentNode pointer to the already 
        // existing node for current character.
        currentNode = currentNode.childNode[c - 'a'];
    }

    // Prefix exist in the Trie
    return true;
}
Javascript
function isPrefixExist(root, key) {
    // Initialize the currentNode pointer with the root node
    let currentNode = root;

    // Iterate across the length of the string
    for (let c of key) {

        // Check if the node exist for the current character in the Trie.
        if (currentNode.childNode[c.charCodeAt(0) - 'a'.charCodeAt(0)] === null) {
          
            // Given word as a prefix does not exist in Trie
            return false;
        }

        // Move the currentNode pointer to the already existing node for current character.
        currentNode = currentNode.childNode[c.charCodeAt(0) - 'a'.charCodeAt(0)];
    }

    // Prefix exist in the Trie
    return true;
}

2.2 Searching Complete word in Trie Data Structure:

It is similar to prefix search but additionally, we have to check if the word is ending at the last character of the word or not.

Search “dad” in the Trie data structure

Implementation of Search in Trie data structure:

C++
bool search_key(TrieNode* root, string& key)
{
    // Initialize the currentNode pointer
    // with the root node
    TrieNode* currentNode = root;

    // Iterate across the length of the string
    for (auto c : key) {

        // Check if the node exist for the current
        // character in the Trie.
        if (currentNode->childNode[c - 'a'] == NULL) {
          
            // Given word does not exist in Trie
            return false;
        }

        // Move the currentNode pointer to the already 
        // existing node for current character.
        currentNode = currentNode->childNode[c - 'a'];
    }
 
    return (currentNode->wordCount > 0);
}
Java
// Returns true if key presents in trie, else false
static boolean search(TrieNode root, String key)
{
    // Initialize the currentNode
    // with the root node
    TrieNode currentNode = root;

    for (int i = 0; i < key.length(); i++) {
        int index = key.charAt(i) - 'a';

        // Check if the node exist for the current
        // character in the Trie.
        if (currentNode.childNode[index] == null)
            return false;

        // Move the currentNode to the already
        // existing node for current character.
        currentNode = currentNode.childNode[index];
    }

    return (currentNode.isEndOfWord);
}
Python3
def search_key(root, key):
    # Initialize the currentNode pointer with the root node
    currentNode = root

    # Iterate across the length of the string
    for c in key:
        # Check if the node exist for the current character in the Trie
        if currentNode.childNode[ord(c) - ord('a')] is None:
            # Given word does not exist in Trie
            return False

        # Move the currentNode pointer to the already existing node for current character
        currentNode = currentNode.childNode[ord(c) - ord('a')]
 
    # Return if the wordCount is greater than 0
    return currentNode.wordCount > 0
C#
public bool SearchKey(TrieNode root, string key)
{
// Initialize the currentNode pointer with the root node
TrieNode currentNode = root;
  // Iterate across the length of the string
foreach (char c in key)
{
    // Check if the node exist for the current character in the Trie
    if (currentNode.childNode[c - 'a'] == null)
    {
        // Given word does not exist in Trie
        return false;
    }

    // Move the currentNode pointer to the already existing node for current character
    currentNode = currentNode.childNode[c - 'a'];
}

// Return if the wordCount is greater than 0
return currentNode.wordCount > 0;
}

//This code is contributed by shivamsharma215
Javascript
function searchKey(root, key) {
  let currentNode = root;

  for (let c of key) {
    if (!currentNode.childNode[c.charCodeAt(0) - 'a'.charCodeAt(0)]) {
      return false;
    }
    currentNode = currentNode.childNode[c.charCodeAt(0) - 'a'.charCodeAt(0)];
  }

  return currentNode.wordCount > 0;
}

Trie Data Structure Tutorial

The trie data structure, also known as a prefix tree, is a tree-like data structure used for efficient retrieval of key-value pairs. It is commonly used for implementing dictionaries and autocomplete features, making it a fundamental component in many search algorithms. In this article, we will explore all about Trie data structures in detail.

Trie Data Structure

Table of Content

  • What is Trie Data Structure?
  • What is need of Trie Data Structure?
  • Advantages of Trie Data Structure over a Hash Table
  • Properties of a Trie Data Structure
  • How does Trie Data Structure work?
  • Representation of Trie Node
  • Basic Operations on Trie Data Structure
  • Insertion in Trie Data Structure
  • Searching in Trie Data Structure
  • Deletion in Trie Data Structure
  • Implement Trie Data Structure?
  • Complexity Analysis of Trie Data Structure
  • Applications of Trie data structure
  • Advantages of Trie data structure
  • Disadvantages of Trie data structure
  • Top Interview problems on Trie data structure

Similar Reads

What is Trie Data Structure?

Trie data structure is defined as a Tree based data structure that is used for storing some collection of strings and performing efficient search operations on them. The word Trie is derived from reTRIEval, which means finding something or obtaining it....

What is need of Trie Data Structure?

A Trie data structure is used for storing and retrieval of data and the same operations could be done using another data structure which is Hash Table but Trie data structure can perform these operations more efficiently than a Hash Table. Moreover, Trie has its own advantage over the Hash table. A Trie data structure can be used for prefix-based searching whereas a Hash table can’t be used in the same way....

Advantages of Trie Data Structure over a Hash Table:

The A trie data structure has the following advantages over a hash table:...

Properties of a Trie Data Structure

Below are some important properties of the Trie data structure:...

How does Trie Data Structure work?

Trie data structure can contain any number of characters including alphabets, numbers, and special characters. But for this article, we will discuss strings with characters a-z. Therefore, only 26 pointers need for every node, where the 0th index represents ‘a’ and the 25th index represents ‘z’ characters....

Representation of Trie Node:

Every Trie node consists of a character pointer array or hashmap and a flag to represent if the word is ending at that node or not. But if the words contain only lower-case letters (i.e. a-z), then we can define Trie Node with an array instead of a hashmap....

Basic Operations on Trie Data Structure:

InsertionSearchDeletion...

1. Insertion in Trie Data Structure:

This operation is used to insert new strings into the Trie data structure. Let us see how this works:...

2. Searching in Trie Data Structure:

Search operation in Trie is performed in a similar way as the insertion operation but the only difference is that whenever we find that the array of pointers in curr node does not point to the current character of the word then return false instead of creating a new node for that current character of the word....

3. Deletion in Trie Data Structure

This operation is used to delete strings from the Trie data structure. There are three cases when deleting a word from Trie....

Implement Trie Data Structure?

Algorithm:...

Complexity Analysis of Trie Data Structure

OperationTime ComplexityAuxiliary SpaceInsertionO(n)O(n*m)SearchingO(n)O(1)DeletionO(n)O(1)...

Applications of Trie data structure:

1. Autocomplete Feature: Autocomplete provides suggestions based on what you type in the search box. Trie data structure is used to implement autocomplete functionality....

Advantages of Trie data structure:

Trie allows us to input and finds strings in O(l) time, where l is the length of a single word. It is faster as compared to both hash tables and binary search trees.It provides alphabetical filtering of entries by the key of the node and hence makes it easier to print all words in alphabetical order.Trie takes less space when compared to BST because the keys are not explicitly saved instead each key requires just an amortized fixed amount of space to be stored.Prefix search/Longest prefix matching can be efficiently done with the help of trie data structure.Since trie doesn’t need any hash function for its implementation so they are generally faster than hash tables for small keys like integers and pointers.Tries support ordered iteration whereas iteration in a hash table will result in pseudorandom order given by the hash function which is usually more cumbersome.Deletion is also a straightforward algorithm with O(l) as its time complexity, where l is the length of the word to be deleted....

Disadvantages of Trie data structure:

The main disadvantage of the trie is that it takes a lot of memory to store all the strings. For each node, we have too many node pointers which are equal to the no of characters in the worst case.An efficiently constructed hash table(i.e. a good hash function and a reasonable load factor) has O(1) as lookup time which is way faster than O(l) in the case of a trie, where l is the length of the string....

Top Interview problems on Trie data structure:

S.noProblemPractice1Implement Trie (Prefix Tree)Link2Word Break ProblemLink3BoggleLink4Longest Common Prefix using TrieLink5Find the maximum subarray XOR in a given arrayLink6Count of distinct substrings of a stringLink7Find shortest unique prefix for every word in a given list Link8Count inversions in an arrayLink...

Frequently asked questions (FAQs) about Trie Data Structure:

Is trie an advanced data structure?...

Conclusion:

Our discussion so far has led us to the conclusion that the Trie data structure is a Tree based data structure that is used for storing some collection of strings and performing efficient search operations on them and we have also discussed the various advantage and applications of trie data structure....