Trie Data Structure in C++
Last Updated :
28 Jun, 2024
A Trie, also known as a prefix tree, is a tree-like data structure used to store a dynamic set of strings. It is particularly useful for efficient retrieval of keys in a large dataset of strings. In this article, we will explore the Trie data structure, its operations, implementation in C++, and its advantages, disadvantages, and applications.
What is a Trie?
A Trie data structure is a tree-like data structure where each node represents a character of a string sequence. 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. This structure allows for efficient insertion, deletion, and search operations.
For example, if we consider a Trie for storing strings with only lowercase 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 will represent a single character of the string.
- The root node represents an empty string.
- Each path of the tree represents a word.
- Each node of the trie will have 26 pointers to represent the letters from a-z.
- A boolean flag is used to mark the end of a word in the path of a Trie.
Trie Representation in C++
To represent a node of a Trie in C++, we can declare a class TrieNode in which each node contains an array of pointers to its children and a boolean flag to indicate the end of a word.
class TrieNode {
TrieNode* childrens[26];
bool endofWord;
};
Here,
- childrens[]: is an array of pointers to represent the children of each trie node. To represent letters from a-z the size of the array is declared as 26 where children[0] represents a, children[1] represents b and so on.
- endofWord: is a flag variable that will denote the end of a word in a path of the trie. At any node if the value of endofWord is true it indicates the end of a word in the trie.
The following diagram represents how the words geek, geeks, code, coder and coding will be stored in a Trie:
Example: Trie Data StructureBasic operations on Trie Data Structure
Following are some of the basic operations performed on a Trie data structure:
Operation | Description | Time Complexity | Space Complexity |
---|
Insert | Inserts a new word into the trie. | O(n) | O(n) |
---|
Search | Searches for a word in the trie. | O(n) | O(1) |
---|
Delete | Removes a word from the trie. | O(n) | O(1) |
---|
StartsWith | Checks if there is any word in the trie that starts with the given prefix | O(m) | O(1) |
---|
Here, n represents the length of the word and m represents the length of the prefix.
Insertion Implementation
Following is the algorithm for inserting a word in a trie:
- Initialize a temporary pointer to the root node of the trie.
- For each character in the word:
- Find the index of the character.
- If the character doesn't exists in the current node's children, create a new node for this character.
- Move the pointer to the child node.
- Mark the last node's as the endofWord as true.
Search Implementation
Following is the algorithm for searching a word in a trie:
- Initialize a temporary pointer to the root node of the trie.
- For each character of the word:
- Calculate the index of the character.
- If the corresponding child node doesn't exists return false and return.
- If the child node exists move the pointer to the child node.
- Return true if the endofWord of the last character is true otherwise return false.
Deletion Implementation
Following is the algorithm for deleting a word in a trie:
- Initialize a temporary pointer to the root node of the trie.
- For each character of the word to be deleted:
- Calculate the index of the character.
- If the corresponding child node doesn't; exists return as the word is not present in the trie.
- If the child node exists move the pointer to the child node.
- If the endofWord for the child node is true mark it false and return.
StartsWith Operation Implementation
Following is the algorithm to check if a prefix exits in a trie or not:
- Initialize a temporary pointer to the root node of the trie.
- For each character of the prefix:
- Calculate the index of the character.
- If the corresponding child node doesn't exists return false and return.
- If the child node exists move the pointer to the child node.
- Return true if you have reached at the last character of the prefix.
C++ Program to Implement Trie Data Structure
The following program demonstrates the basic operations on a Trie: insertion, searching, and deletion.
C++
// C++ Program to implement trie
#include <iostream>
#include <string>
using namespace std;
// class for a node of the trie
class TrieNode {
public:
bool endofWord;
TrieNode* children[26];
// Constructore to initialize a trie node
TrieNode()
{
endofWord = false;
for (int i = 0; i < 26; i++) {
children[i] = nullptr;
}
}
};
// class for the Trie implementation
class Trie {
private:
TrieNode* root;
public:
Trie() { root = new TrieNode(); }
// Function to insert a word into the trie
void insert(string word)
{
TrieNode* node = root;
for (char c : word) {
int index = c - 'a';
if (!node->children[index]) {
node->children[index] = new TrieNode();
}
node = node->children[index];
}
node->endofWord = true;
}
// Function to search a word in the trie
bool search(string word)
{
TrieNode* node = root;
for (char c : word) {
int index = c - 'a';
if (!node->children[index]) {
return false;
}
node = node->children[index];
}
return node->endofWord;
}
// Function to check if there is any word in the trie
// that starts with the given prefix
bool startsWith(string prefix)
{
TrieNode* node = root;
for (char c : prefix) {
int index = c - 'a';
if (!node->children[index]) {
return false;
}
node = node->children[index];
}
return true;
}
// Function to delete a word from the trie
void deleteWord(string word)
{
TrieNode* node = root;
for (char c : word) {
int index = c - 'a';
if (!node->children[index]) {
return;
}
node = node->children[index];
}
if (node->endofWord == true) {
node->endofWord = false;
}
}
// Function to print the trie
void print(TrieNode* node, string prefix) const
{
if (node->endofWord) {
cout << prefix << endl;
}
for (int i = 0; i < 26; i++) {
if (node->children[i]) {
print(node->children[i],
prefix + char('a' + i));
}
}
}
// Function to start printing from the root
void print() const { print(root, ""); }
};
int main()
{
// Create a Trie
Trie trie;
// Insert words into the trie
trie.insert("geek");
trie.insert("geeks");
trie.insert("code");
trie.insert("coder");
trie.insert("coding");
// Print the trie
cout << "Trie contents:" << endl;
trie.print();
// Search for words in the trie
cout << "\nSearch results:" << endl;
cout << "geek: " << trie.search("geek") << endl;
cout << "geeks: " << trie.search("geeks") << endl;
cout << "code: " << trie.search("code") << endl;
cout << "coder: " << trie.search("coder") << endl;
cout << "coding: " << trie.search("coding") << endl;
cout << "codex: " << trie.search("codex") << endl;
// Check if prefixes exist in the trie
cout << "\nPrefix results:" << endl;
cout << "ge: " << trie.startsWith("ge") << endl;
cout << "cod: " << trie.startsWith("cod") << endl;
cout << "coz: " << trie.startsWith("coz") << endl;
// Delete words from the trie
trie.deleteWord("coding");
trie.deleteWord("geek");
// Print the trie after deletions
cout << "\nTrie contents after deletions:" << endl;
trie.print();
// Search for words in the trie after deletions
cout << "\nSearch results after deletions:" << endl;
cout << "coding: " << trie.search("coding") << endl;
cout << "geek: " << trie.search("geek") << endl;
return 0;
}
Output
Trie contents:
code
coder
coding
geek
geeks
Search results:
geek: 1
geeks: 1
code: 1
coder: 1
coding: 1
codex: 0
Prefix results:
ge: 1
cod: 1
coz: 0
Trie contents after deletions:
code
coder
geeks
Search results after deletions:
coding: 0
geek: 0
Applications of Trie
Following are some of the common applications of the trie data structure:
- Tries are used to implement the auto complete feature in various search engines.
- Used to implement dictionaries as the allow efficient search for words.
- Used in computer networking to store the routing tables.
- Used by the search engines to index web pages for quick retrieval of pages containing specific keywords.
- Used in phone directory applications to allows users to search for the required contacts efficiently.
Advantages of Trie
- Tries provide efficient search operations with a time complexity of O(m), where m is the length of the key.
- Tries are ideal for prefix-based searches and autocomplete features.
- Tries can be more memory-efficient than hash tables for storing large datasets of strings.
Disadvantages of Trie
- Tries can consume a lot of memory, especially when storing a large number of short strings.
- Implementing a Trie can be more complex compared to other data structures like hash tables.
Related Articles:
You can also go through the following articles to improve your understanding about the trie data structure:
Similar Reads
C++ Programming Language C++ is a computer programming language developed by Bjarne Stroustrup as an extension of the C language. It is known for is fast speed, low level memory management and is often taught as first programming language. It provides:Hands-on application of different programming concepts.Similar syntax to
5 min read
Non-linear Components In electrical circuits, Non-linear Components are electronic devices that need an external power source to operate actively. Non-Linear Components are those that are changed with respect to the voltage and current. Elements that do not follow ohm's law are called Non-linear Components. Non-linear Co
11 min read
Spring Boot Tutorial Spring Boot is a Java framework that makes it easier to create and run Java applications. It simplifies the configuration and setup process, allowing developers to focus more on writing code for their applications. This Spring Boot Tutorial is a comprehensive guide that covers both basic and advance
10 min read
Object Oriented Programming in C++ Object Oriented Programming - As the name suggests uses objects in programming. Object-oriented programming aims to implement real-world entities like inheritance, hiding, polymorphism, etc. in programming. The main aim of OOP is to bind together the data and the functions that operate on them so th
5 min read
Class Diagram | Unified Modeling Language (UML) A UML class diagram is a visual tool that represents the structure of a system by showing its classes, attributes, methods, and the relationships between them. It helps everyone involved in a projectâlike developers and designersâunderstand how the system is organized and how its components interact
12 min read
Backpropagation in Neural Network Back Propagation is also known as "Backward Propagation of Errors" is a method used to train neural network . Its goal is to reduce the difference between the modelâs predicted output and the actual output by adjusting the weights and biases in the network.It works iteratively to adjust weights and
9 min read
3-Phase Inverter An inverter is a fundamental electrical device designed primarily for the conversion of direct current into alternating current . This versatile device , also known as a variable frequency drive , plays a vital role in a wide range of applications , including variable frequency drives and high power
13 min read
30 OOPs Interview Questions and Answers [2025 Updated] Object-oriented programming, or OOPs, is a programming paradigm that implements the concept of objects in the program. It aims to provide an easier solution to real-world problems by implementing real-world entities such as inheritance, abstraction, polymorphism, etc. in programming. OOPs concept is
15 min read
Polymorphism in Java Polymorphism in Java is one of the core concepts in object-oriented programming (OOP) that allows objects to behave differently based on their specific class type. The word polymorphism means having many forms, and it comes from the Greek words poly (many) and morph (forms), this means one entity ca
7 min read
What is Vacuum Circuit Breaker? A vacuum circuit breaker is a type of breaker that utilizes a vacuum as the medium to extinguish electrical arcs. Within this circuit breaker, there is a vacuum interrupter that houses the stationary and mobile contacts in a permanently sealed enclosure. When the contacts are separated in a high vac
13 min read