Skip to content

feat: add Trie Data Structure #5491

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
83 changes: 83 additions & 0 deletions src/main/java/com/thealgorithms/datastructures/tries/Trie.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.thealgorithms.datastructures.tries;

/**
* Trie class which holds Strings of characters.
*
* <a href="https://en.wikipedia.org/wiki/Trie">Wikipedia</a>
*
* @author <a href="https://github.com/sailok">Sailok Chinta</a>
*/
public class Trie {
private static final char ROOT_CHAR = '*';

private final TrieNode root;

public Trie() {
this.root = new TrieNode(ROOT_CHAR);
}

/**
* Inserts the word into Trie
*
* @param word
*/
public void insert(String word) {
TrieNode head = root;

for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);

if (!head.getChildren().containsKey(c)) {
head.getChildren().put(c, new TrieNode(c));
}

head = head.getChildren().get(c);
}

head.setEnd(true);
}

/**
* Searches in the Trie if a word exists or not.
*
* @param word
* @return true / false
*/
public boolean search(String word) {
TrieNode head = root;

for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);

if (!head.getChildren().containsKey(c)) {
return false;
}

head = head.getChildren().get(c);
}

return head.isEnd();
}

/**
* Searches in the Trie if a prefix exists or not.
*
* @param prefix
* @return true / false
*/
public boolean startsWith(String prefix) {
TrieNode head = root;

for (int i = 0; i < prefix.length(); i++) {
char c = prefix.charAt(i);

if (!head.getChildren().containsKey(c)) {
return false;
}

head = head.getChildren().get(c);
}

return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.thealgorithms.datastructures.tries;

import java.util.HashMap;
import java.util.Map;

/**
* TrieNode class which holds the characters and references to its child nodes
*
* <a href="https://en.wikipedia.org/wiki/Trie">Wikipedia</a>
*
* @author <a href="https://github.com/sailok">Sailok Chinta</a>
*/
public class TrieNode {
private Map<Character, TrieNode> children;
private char value;
private boolean end;

public TrieNode(char value) {
this.value = value;
this.children = new HashMap<>();
this.end = false;
}

public Map<Character, TrieNode> getChildren() {
return children;
}

/*
public void setChildren(Map<Character, TrieNode> children) {
this.children = children;
}
*/

public char getValue() {
return value;
}

public void setValue(char value) {
this.value = value;
}

public boolean isEnd() {
return end;
}

public void setEnd(boolean end) {
this.end = end;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.thealgorithms.datastructures.tries;

import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class TrieTest {
private static final List<String> WORDS = List.of("apple", "app", "rest", "rent", "rental");

@Test
void searchInTrieSuccess() {
Trie trie = new Trie();

for (String word : WORDS) {
trie.insert(word);
}

Assertions.assertTrue(trie.search("app"));
Assertions.assertTrue(trie.search("apple"));
Assertions.assertFalse(trie.search("apply"));
}

@Test
void startsWithPrefixInTrieSuccess() {
Trie trie = new Trie();

for (String word : WORDS) {
trie.insert(word);
}

Assertions.assertTrue(trie.startsWith("app"));
Assertions.assertTrue(trie.startsWith("re"));
Assertions.assertTrue(trie.startsWith("rent"));
Assertions.assertFalse(trie.startsWith("bike"));
}
}