C++ Program to Implement Trie



A Trie, also known as a prefix tree, is used to store and search for large sets of strings. In this section we will discuss all about Trie data structure, its operations, and how to implement it in C++.

Trie Data Structure

A Trie is a data structure similar to a tree that is used to store a dynamic set of strings. The root node represents an empty string, and each edge represents a character. The path from the root to a node represents a prefix of a string stored in the Trie. The image below show how a trie stores the words "Tutorials", "Tutorialspoint", "code", "coder" and "coding".

Trie Data Structure

For example, if we want a Trie to store strings with only lowercase english characters, then each node of the trie will consist of 26 children each representing the presence of letters from a-z. Following are some properties of the trie data structure:

  • Each node in the Trie represents a character of the string.
  • Each path from the root to a node represents a prefix of a string stored in the Trie.
  • The root node represents an empty string.
  • Each node can have multiple children, but only one parent.

Representing a Trie in C++

To represent a Trie in C++, we can use a class with a vector of pointers to its children and a boolean flag to indicate if the node represents the end of a word. Below is an example of how to implement a Trie in C++:

class TrieNode {
public:
    TrieNode* child[26];
    bool isEndOfWord;
}; 

Basic Operations on Trie

The basic insertion, search, and deletion operations can be implemented on a trie data structure. The section below will explain how to implement each of these operations.

1. Insertion in Trie

To insert a word into the Trie, we can follow the algorithm below:

  • Start from the root node.
  • For each character in the word, check if the corresponding child node exists.
  • If the child node does not exist, create a new TrieNode.
  • Move to the child node and repeat the process for the next character.
  • After inserting all characters, mark the last node as the end of the word.

2. Search in Trie

To search for a word in the Trie, we can follow the algorithm below:

  • Start from the root node.
  • For each character in the word, check if the corresponding child node exists.
  • If the child node does not exist, return false.
  • Then, move to the child node and repeat the process for the next character.
  • If you reach the end of the word and the last node is marked as end of word, return true.

3. Deletion in Trie

You can use the following algorithm to delete a word from the Trie:

  • Start from the root node.
  • For each character in the word, check if the corresponding child node exists.
  • If the child node does not exist, return.
  • Move to the child node and repeat the process for the next character.
  • After reaching the end of the word, mark the last node as not end of word.
  • If the last node has no children, delete it and backtrack to remove any unnecessary nodes.

C++ Code to Implement Trie

The code below implements a Trie data structure in C++ with insertion, search, and deletion operations.

#include <iostream>
using namespace std;

const int ALPHABET_SIZE = 26;

// Trie Node
struct TrieNode {
    TrieNode* children[ALPHABET_SIZE];
    bool isEndOfWord;

    TrieNode() {
        isEndOfWord = false;
        for (int i = 0; i < ALPHABET_SIZE; i++)
            children[i] = nullptr;
    }
};

// Trie class
class Trie {
private:
    TrieNode* root;

    // Helper function to delete word
    bool deleteHelper(TrieNode* node, const string& word, int depth) {
        if (!node) return false;

        if (depth == word.size()) {
            // Word found
            if (!node->isEndOfWord) return false;
            node->isEndOfWord = false;

            // If node has no children, it can be deleted
            for (int i = 0; i < ALPHABET_SIZE; i++)
                if (node->children[i])
                    return false;

            return true; // Delete this node
        }

        int index = word[depth] - 'a';
        if (deleteHelper(node->children[index], word, depth + 1)) {
            delete node->children[index];
            node->children[index] = nullptr;

            // If current node is not end of another word and has no children
            return !node->isEndOfWord && isEmpty(node);
        }

        return false;
    }

    bool isEmpty(TrieNode* node) {
        for (int i = 0; i < ALPHABET_SIZE; i++)
            if (node->children[i])
                return false;
        return true;
    }

public:
    Trie() {
        root = new TrieNode();
    }

    // Insert word into trie
    void insert(const string& word) {
        TrieNode* curr = root;
        for (char ch : word) {
            int index = ch - 'a';
            if (!curr->children[index])
                curr->children[index] = new TrieNode();
            curr = curr->children[index];
        }
        curr->isEndOfWord = true;
    }

    // Search for a word
    bool search(const string& word) {
        TrieNode* curr = root;
        for (char ch : word) {
            int index = ch - 'a';
            if (!curr->children[index])
                return false;
            curr = curr->children[index];
        }
        return curr->isEndOfWord;
    }

    // Delete a word
    void remove(const string& word) {
        deleteHelper(root, word, 0);
    }
};

int main() {
    Trie trie;

    trie.insert("hello");
    cout << "Inserted 'hello'" << endl;
    trie.insert("hell");
    cout << "Inserted 'hell'" << endl;
    trie.insert("help");
    cout << "Inserted 'help'" << endl;

    cout << "Search 'hell': " << trie.search("hell") << endl;  // true
    cout << "Search 'help': " << trie.search("help") << endl;  // true
    cout << "Search 'helix': " << trie.search("helix") << endl;  // false

    trie.remove("hell");
    cout << "Search 'hell' after deletion: " << trie.search("hell") << endl;  // false
    cout << "Search 'hello': " << trie.search("hello") << endl;  // true (should still exist)

    return 0;
}

The output of the above code will be:

Inserted 'hello'
Inserted 'hell'
Inserted 'help'
Search 'hell': 1
Search 'help': 1
Search 'helix': 0
Search 'hell' after deletion: 0
Search 'hello': 1

Time and Space Complexity of Trie

Time Complexity: The time complexity for insertion, search, and deletion operations in a Trie is O(m), where m is the length of the word being inserted, searched, or deleted.

Space Complexity: The space complexity of a Trie is O(n * m), where n is the number of words stored in the Trie and m is the average length of the words.

Farhan Muhamed
Farhan Muhamed

No Code Developer, Vibe Coder

Updated on: 2025-07-15T18:04:38+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements