Golang program to implement a Trie data structure


A trie is a data structure like tree that is used to store and search a dynamic set of strings. It is useful while working with the data where keys share common prefix like dictionary words. Trie is different from the other retrieval data structures owing to its efficient string manipulation and retrieval properties. In this article we will learn to implement Trie data structure in Go programming language.

Explanation

The Trie, also known as a retrieval tree is a type of tree data structure that is commonly used for storing and managing collections of strings. It offers access, to stored strings. Supports various operations like insertion and deletion. This makes it particularly useful, for tasks that involve searching and providing suggestions.

Let us see the trie tree

           (root)
          /  |  \
         a   b   b
        /     \   \
       p       a   a
      /|        \   \
     p p         t   l
    /   \         \
   l    le         l
  /
 e
  • We have a root node on the top,with no character.

  • Edges connect nodes and each edge represents a character.

  • Nodes can have many childs, and characters.

  • The path a->p->p->l->e, represents apple.

  • The path b->a->t represent bat

Syntax

func NewTrie() *Trie

The syntax defines a function named NewTrie() defined to initialize a new instance of the Trie with a root node that contains a map for children nodes.

func (t *Trie) StartsWith(prefix string) (words []string)

The syntax defines a function StartsWith which for a given prefix, navigates through the Trie to identify words that share that prefix, by recursively traversing the nodes from the root to the prefix. It gathers words found under that prefix and returns them as a list.

Algorithm

  • Start by creating a TrieNode type structure having a map to store child nodes.

  • Then define an Insert function to add a word to the Trie.

  • Develop a Search function to check if a word exists in the Trie.

  • Build a StartsWith function to find all words with a given prefix.

  • Finally, design a Print function to visualize the Trie structure.

Example

In this example, we have defined a Trie data structure using a TrieNode structure including a map to store child nodes and a boolean value to mark the end of words. The Insert function helps in adding strings by iterating through characters and creating nodes as needed. Search function traverses the Trie for determining if a word exists. Finally, printTrie function visually displays the Trie's structure.

package main
import "fmt"
type TrieNode struct{ children map[rune]*TrieNode; isEnd bool }
type Trie struct{ root *TrieNode }
func NewTrie() *Trie { return &Trie{root: &TrieNode{children: make(map[rune]*TrieNode)}}}
func (t *Trie) Insert(word string) {
	node := t.root
	for _, c := range word {
     	if node.children[c] == nil { node.children[c] = &TrieNode{children: make(map[rune]*TrieNode)}}
    	node = node.children[c]
    }
	node.isEnd = true
}
func (t *Trie) Search(word string) bool {
	node := t.root
	for _, c := range word {
     	if node.children[c] == nil { return false }
    	node = node.children[c]
	}
	return node.isEnd
}
func printTrie(node *TrieNode, level int, prefix string) {
    if node == nil { return }
	fmt.Printf("%s%d\n", prefix, level)
	for c, childNode := range node.children {
    	printTrie(childNode, level+1, fmt.Sprintf("%s──", prefix))
    	fmt.Printf("%s%s\n", prefix, string(c))
    }
}
func main() {
	trie := NewTrie()
	words := []string{"apple", "app", "banana", "bat"}
	for _, w := range words { trie.Insert(w); }
	fmt.Println("\nTrie Structure:"); printTrie(trie.root, 0, "")
	fmt.Println("\nSearch 'app':", trie.Search("app")) 
	fmt.Println("Search 'banana':", trie.Search("banana")) 
	fmt.Println("Search 'batman':", trie.Search("batman"))
}

Output

Trie Structure:
0
──1
────2
──────3
────────4
──────────5
────────e
──────l
────p
──p
a
──1
────2
──────3
────────4
──────────5
────────────6
──────────a
────────n
──────a
────n
──────3
────t
──a
b

Search 'app': true
Search 'banana': true
Search 'batman': false

Real Life Implementation

  • Contacts or Phonebook Applications: Attempts to manage contact information may be used to develop contact or phonebook applications. The trie data structure allows for the encoding of particular characters in a contact's name through its nodes, making it possible to search for contacts by entering partial names.

  • Auto-Completion in IDEs: As a prevalent feature in Integrated Development Environments (IDEs), code auto-completion demands simplified implementation. Tries help to rapidly identify valid code snippets which will match the input prefix for a streamlined experience.

Conclusion

The Trie data structure is a fundamental tool for string manipulation, offering efficient storage and retrieval of words. In this article, we explored the concept of the Trie, implementing Trie data structure in Go using two different methods. The first method emphasizes on insertion and searching to highlight Trie's appropriateness for word lookups in dictionaries or spell checkers. The second method introduces Trie's versatility by implementing prefix matching, useful for tasks like autocomplete or suggestions.

Updated on: 18-Oct-2023

184 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements