Nongeneric string trie implementation in java with textual tree visualisation capability. supports insert, search word, search prefix, delete
public class StringTrie {
private static final class TrieNode{
Map<Character , TrieNode> child = new TreeMap<>();
boolean isEndNode = false;
public void print() {
print("", true,'$');
}
private void print(String prefix, boolean isTail, char name) {
System.out.println(prefix + (isTail ? "└── " : "├── ") + name+ (isEndNode?"*":""));
Map.Entry<Character,TrieNode> lastEntry = null;
int i = 0;
for (Map.Entry<Character,TrieNode> entry: child.entrySet()) {
char c = entry.getKey();
if(i < child.size()-1)
entry.getValue().print(prefix + (isTail ? " " : "│ "), false,c);
else
entry.getValue().print(prefix + (isTail ?" " : "│ "), true,c);
i++; if (child.size() > 0) {
}
}
}
}
private TrieNode root = new TrieNode();
public void insert(String s){
insert(s,root);
return;
}
private void insert(String s, TrieNode root) {
if(s.length() == 0){
root.isEndNode = true;
}
for(int i = 0 ; i < s.length() ; i++){
char c = s.charAt(i);
TrieNode node = root.child.get(c);
if(node == null){
node = new TrieNode();
root.child.put(c , node);
}
node.isEndNode |= i==s.length() - 1;
root = node;
}
}
public boolean searchPrefix(String prefix){
return getPrefixNode(prefix , root)!=null;
}
public boolean searchWord(String prefix){
TrieNode current =getPrefixNode(prefix , root);
return current != null && current.isEndNode;
}
private TrieNode getPrefixNode( String prefix , TrieNode root){
TrieNode current = root;
for(int i = 0; i < prefix.length() ; i++){
current = current.child.get(prefix.charAt(i));
if(current == null)
return null;
}
return current;
}
public boolean deleteWord(String word){
if(word.length() == 0)
{
boolean ret = root.isEndNode;
root.isEndNode = false;
return ret;
}
TrieNode current = root;
Stack<TrieNode > nodeStack = new Stack<>();
for(int i = 0; i < word.length() ; i++){
current = current.child.get(word.charAt(i));
if(current == null)
return false;
nodeStack.push(current);
}
if(!current.isEndNode){
return false;
}
current.isEndNode = false;
current = nodeStack.pop();
for(int i = word.length()-1 ; i >=0 ; i--){
if(current.child.size() == 0 && !current.isEndNode){
current = nodeStack.pop();
current.child.remove(word.charAt(i));
}else{
break;
}
}
return true;
}
public static void main(String... args){
StringTrie trie = new StringTrie();
trie.insert("abc");
trie.insert("abgl");
trie.insert("cdf");
trie.insert("abcd");
trie.insert("abcd");
trie.insert("lmn");
assert trie.searchPrefix("abcd"); trie.root.print();
assert trie.searchPrefix("a"); trie.root.print();
assert !trie.searchPrefix("lmng"); trie.root.print();
assert trie.searchPrefix("ab"); trie.root.print();
assert trie.searchWord("abcd"); trie.root.print();
assert trie.searchWord("abc"); trie.root.print();
assert !trie.searchWord("ab"); trie.root.print();
assert !trie.searchWord("ff"); trie.root.print();
assert !trie.deleteWord(""); trie.root.print();
trie.insert("");
assert trie.deleteWord(""); trie.root.print();
assert trie.deleteWord("abcd"); trie.root.print();
assert !trie.deleteWord("abcd"); trie.root.print();
System.out.println();
}
}