Bird
Raised Fist0
DSA Cprogramming

Trie Insert Operation in DSA C

Choose your learning style10 modes available
Mental Model
A trie stores words by branching letters step-by-step, sharing common prefixes to save space.
Analogy: Imagine a tree of roads where each letter is a turn; inserting a word means building new roads only where needed.
root
 ↓
 [ ]
Each node has links for letters a-z, initially empty.
Dry Run Walkthrough
Input: Insert words: "cat", then "car" into an empty trie
Goal: Build a trie that stores both words sharing the prefix 'ca'
Step 1: Insert 'c' from 'cat' at root node
root -> c -> [ ]
(c node created)
Why: We create a new branch for the first letter 'c' since trie is empty
Step 2: Insert 'a' after 'c'
root -> c -> a -> [ ]
(a node created under 'c')
Why: Add next letter 'a' as child of 'c' to continue word
Step 3: Insert 't' after 'a' and mark end of word
root -> c -> a -> t* -> [ ]
(t node created and marked end)
Why: Complete word 'cat' by adding 't' and marking word end
Step 4: Insert 'c' from 'car' at root (exists)
root -> c -> a -> t* -> [ ]
(c node reused)
Why: Reuse existing 'c' node for new word 'car'
Step 5: Insert 'a' after 'c' (exists)
root -> c -> a -> t* -> [ ]
(a node reused)
Why: Reuse existing 'a' node since prefix matches
Step 6: Insert 'r' after 'a' and mark end of word
root -> c -> a -> t* -> r* -> [ ]
(r node created and marked end)
Why: Add new branch 'r' to complete 'car' word
Result:
root -> c -> a -> t* -> r* -> [ ]
Words 'cat' and 'car' stored sharing prefix 'ca'
Annotated Code
DSA C
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define ALPHABET_SIZE 26

// Trie node structure
typedef struct TrieNode {
    struct TrieNode* children[ALPHABET_SIZE];
    bool isEndOfWord;
} TrieNode;

// Create a new trie node
TrieNode* getNode() {
    TrieNode* node = (TrieNode*)malloc(sizeof(TrieNode));
    node->isEndOfWord = false;
    for (int i = 0; i < ALPHABET_SIZE; i++)
        node->children[i] = NULL;
    return node;
}

// Insert a word into the trie
void insert(TrieNode* root, const char* word) {
    TrieNode* curr = root;
    for (int i = 0; word[i] != '\0'; i++) {
        int index = word[i] - 'a';
        if (curr->children[index] == NULL) {
            curr->children[index] = getNode();
        }
        curr = curr->children[index]; // advance curr to next letter node
    }
    curr->isEndOfWord = true; // mark end of word
}

// Helper to print trie contents for verification
void printTrie(TrieNode* root, char str[], int level) {
    if (root->isEndOfWord) {
        str[level] = '\0';
        printf("%s\n", str);
    }
    for (int i = 0; i < ALPHABET_SIZE; i++) {
        if (root->children[i]) {
            str[level] = 'a' + i;
            printTrie(root->children[i], str, level + 1);
        }
    }
}

int main() {
    TrieNode* root = getNode();
    insert(root, "cat");
    insert(root, "car");
    char str[100];
    printTrie(root, str, 0);
    return 0;
}
if (curr->children[index] == NULL) { curr->children[index] = getNode(); }
create new node if letter path does not exist
curr = curr->children[index];
advance current pointer to next letter node
curr->isEndOfWord = true;
mark current node as end of inserted word
OutputSuccess
car cat
Complexity Analysis
Time: O(m) because we process each letter of the word once during insertion
Space: O(m) in worst case when all letters are new and new nodes are created
vs Alternative: Compared to storing words in a list, trie insertion is faster for prefix queries and avoids duplicate prefix storage
Edge Cases
Inserting empty string
No nodes created, root remains unchanged
DSA C
for (int i = 0; word[i] != '\0'; i++) {
Inserting word that is prefix of existing word (e.g. insert 'ca' after 'cat')
Existing nodes reused, end of word marked at prefix node
DSA C
curr->isEndOfWord = true;
Inserting duplicate word
No new nodes created, end of word remains marked
DSA C
if (curr->children[index] == NULL) {
When to Use This Pattern
When you need to store many words sharing prefixes efficiently, use a trie insert pattern to build a prefix tree.
Common Mistakes
Mistake: Not marking the end of word node, causing search failures
Fix: Always set isEndOfWord = true after inserting all letters
Mistake: Creating new nodes even if path exists, causing duplicates
Fix: Check if child node exists before creating new one
Summary
Inserts words letter by letter into a tree structure sharing prefixes.
Use when storing many words to save space and enable fast prefix queries.
The key is to reuse existing nodes for shared prefixes and mark word ends.

Practice

(1/5)
1. What is the main purpose of the insert operation in a Trie data structure?
easy
A. To add a word character by character into the Trie
B. To delete a word from the Trie
C. To search for a word in the Trie
D. To count the number of words in the Trie

Solution

  1. Step 1: Understand the insert operation

    The insert operation adds each character of a word into the Trie, creating nodes if they don't exist.
  2. Step 2: Differentiate from other operations

    Deleting removes words, searching checks presence, counting totals words. Insert specifically adds words.
  3. Final Answer:

    To add a word character by character into the Trie -> Option A
  4. Quick Check:

    Insert = Add word [OK]
Hint: Insert means adding word letters step-by-step [OK]
Common Mistakes:
  • Confusing insert with search or delete
  • Thinking insert counts words
  • Assuming insert removes words
2. Which of the following is the correct way to declare a Trie node structure in C for insertion?
easy
A. typedef struct TrieNode { char* word; struct TrieNode* children[26]; } TrieNode;
B. typedef struct TrieNode { int data; struct TrieNode* next; } TrieNode;
C. typedef struct TrieNode { struct TrieNode* children[26]; bool isEndOfWord; } TrieNode;
D. typedef struct TrieNode { struct TrieNode* left; struct TrieNode* right; } TrieNode;

Solution

  1. Step 1: Identify Trie node components

    A Trie node has an array of pointers for children (26 letters) and a boolean to mark word end.
  2. Step 2: Match with options

    typedef struct TrieNode { struct TrieNode* children[26]; bool isEndOfWord; } TrieNode; matches this structure. Others describe linked list or binary tree nodes, not Trie nodes.
  3. Final Answer:

    typedef struct TrieNode { struct TrieNode* children[26]; bool isEndOfWord; } TrieNode; -> Option C
  4. Quick Check:

    Trie node = children array + end flag [OK]
Hint: Trie nodes have 26 children pointers and end-of-word flag [OK]
Common Mistakes:
  • Using linked list node structure instead of array
  • Confusing Trie with binary tree node
  • Missing end-of-word boolean
3. What will be the output of the following C code snippet after inserting the word "cat" into an empty Trie and checking the isEndOfWord flag at the last node?
TrieNode* root = createNode();
insert(root, "cat");
bool flag = root->children['c' - 'a']->children['a' - 'a']->children['t' - 'a']->isEndOfWord;
printf("%d", flag);
medium
A. 0
B. Runtime error
C. Compilation error
D. 1

Solution

  1. Step 1: Insert "cat" into Trie

    Each character creates or uses existing nodes. The last character 't' node's isEndOfWord is set to true (1).
  2. Step 2: Check isEndOfWord flag

    Accessing the node for 't' and printing isEndOfWord prints 1 because the word ends there.
  3. Final Answer:

    1 -> Option D
  4. Quick Check:

    Inserted word end flag = 1 [OK]
Hint: End node flag is set to true after insert [OK]
Common Mistakes:
  • Assuming isEndOfWord is 0 after insert
  • Indexing children incorrectly
  • Forgetting to set isEndOfWord during insert
4. Consider the following buggy insert function for a Trie in C:
void insert(TrieNode* root, const char* word) {
    TrieNode* node = root;
    for (int i = 0; word[i] != '\0'; i++) {
        int index = word[i] - 'a';
        if (node->children[index] == NULL) {
            node->children[index] = malloc(sizeof(TrieNode));
        }
        node = node->children[index];
    }
    node->isEndOfWord = true;
}
What is the main bug in this code?
medium
A. New nodes are not initialized, leading to garbage values
B. The loop condition is incorrect and may cause infinite loop
C. The isEndOfWord flag is set too early
D. The root pointer is not updated after insertion

Solution

  1. Step 1: Analyze node allocation

    New nodes are allocated with malloc but not initialized, so children pointers and isEndOfWord have garbage values.
  2. Step 2: Consequences of uninitialized nodes

    Uninitialized children can cause incorrect behavior or crashes during further insert/search operations.
  3. Final Answer:

    New nodes are not initialized, leading to garbage values -> Option A
  4. Quick Check:

    Missing initialization = bug [OK]
Hint: Always initialize new Trie nodes after malloc [OK]
Common Mistakes:
  • Ignoring initialization of new nodes
  • Assuming malloc zeros memory
  • Confusing loop condition correctness
5. You want to insert multiple words into a Trie and then count how many words start with the prefix "pre". Which modification to the Trie insert operation helps achieve this efficiently?
hard
A. Store the entire word at each node instead of characters
B. Add a counter in each node that increments every time a word passes through it during insertion
C. Only mark isEndOfWord without any counters
D. Use a linked list instead of an array for children nodes

Solution

  1. Step 1: Understand prefix counting

    To count words with a prefix, each node can keep a count of how many words pass through it.
  2. Step 2: Modify insert to update counters

    During insertion, increment the counter at each node visited. Then prefix count is the counter at prefix's last node.
  3. Final Answer:

    Add a counter in each node that increments every time a word passes through it during insertion -> Option B
  4. Quick Check:

    Prefix count = node counters [OK]
Hint: Use counters in nodes to track prefix occurrences [OK]
Common Mistakes:
  • Not using counters, making prefix count slow
  • Storing full words at nodes wastes space
  • Using linked list slows access
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard