From 0293c65f7744e95b4fb9937be61fd8c35293960e Mon Sep 17 00:00:00 2001 From: Grzegorz Piwowarek Date: Sat, 20 Jan 2018 11:54:24 +0100 Subject: [PATCH] Trie Examples (#3466) * Implement Trie * Implement TrieTest * Delete testDelete method * Refactorings * Refactor Trie * Refactor TrieNode * Refactor Trie --- .../src/main/java/com/baeldung/trie/Trie.java | 76 +++++++++++++++++++ .../main/java/com/baeldung/trie/TrieNode.java | 31 ++++++++ .../test/java/com/baeldung/trie/TrieTest.java | 68 +++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/trie/Trie.java create mode 100644 core-java/src/main/java/com/baeldung/trie/TrieNode.java create mode 100644 core-java/src/test/java/com/baeldung/trie/TrieTest.java diff --git a/core-java/src/main/java/com/baeldung/trie/Trie.java b/core-java/src/main/java/com/baeldung/trie/Trie.java new file mode 100644 index 0000000000..2c4119df71 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/trie/Trie.java @@ -0,0 +1,76 @@ +package com.baeldung.trie; + +public class Trie { + private TrieNode root; + + Trie() { + root = new TrieNode(); + } + + public void insert(String word) { + TrieNode current = root; + for (int i = 0; i < word.length(); i++) { + char ch = word.charAt(i); + TrieNode node = current.getChildren() + .get(ch); + if (node == null) { + node = new TrieNode(); + current.getChildren() + .put(ch, node); + } + current = node; + } + current.setEndOfWord(true); + } + + public boolean find(String word) { + TrieNode current = root; + for (int i = 0; i < word.length(); i++) { + char ch = word.charAt(i); + TrieNode node = current.getChildren() + .get(ch); + if (node == null) { + return false; + } + current = node; + } + return current.isEndOfWord(); + } + + public void delete(String word) { + delete(root, word, 0); + } + + private boolean delete(TrieNode current, String word, int index) { + if (index == word.length()) { + if (!current.isEndOfWord()) { + return false; + } + current.setEndOfWord(false); + return current.getChildren() + .size() == 0; + } + char ch = word.charAt(index); + TrieNode node = current.getChildren() + .get(ch); + if (node == null) { + return false; + } + boolean shouldDeleteCurrentNode = delete(node, word, index + 1); + + if (shouldDeleteCurrentNode) { + current.getChildren() + .remove(ch); + return current.getChildren().isEmpty(); + } + return false; + } + + public boolean containsNode(String word) { + return find(word); + } + + public boolean isEmpty() { + return root == null; + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/trie/TrieNode.java b/core-java/src/main/java/com/baeldung/trie/TrieNode.java new file mode 100644 index 0000000000..25dc753950 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/trie/TrieNode.java @@ -0,0 +1,31 @@ +package com.baeldung.trie; + +import java.util.HashMap; +import java.util.Map; + +class TrieNode { + private Map children; + private boolean endOfWord; + + public TrieNode() { + children = new HashMap<>(); + endOfWord = false; + } + + public Map getChildren() { + return children; + } + + public void setChildren(Map children) { + this.children = children; + } + + public boolean isEndOfWord() { + return endOfWord; + } + + public void setEndOfWord(boolean endOfWord) { + this.endOfWord = endOfWord; + } + +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/trie/TrieTest.java b/core-java/src/test/java/com/baeldung/trie/TrieTest.java new file mode 100644 index 0000000000..be7e5575d8 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/trie/TrieTest.java @@ -0,0 +1,68 @@ +package com.baeldung.trie; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class TrieTest { + + @Test + public void whenEmptyTrie_thenNoElements() { + Trie trie = new Trie(); + + assertFalse(trie.isEmpty()); + } + + @Test + public void givenATrie_whenAddingElements_thenTrieNotEmpty() { + Trie trie = createExampleTrie(); + + assertFalse(trie.isEmpty()); + } + + @Test + public void givenATrie_whenAddingElements_thenTrieHasThoseElements() { + Trie trie = createExampleTrie(); + + assertFalse(trie.containsNode("3")); + assertFalse(trie.containsNode("vida")); + + assertTrue(trie.containsNode("Programming")); + assertTrue(trie.containsNode("is")); + assertTrue(trie.containsNode("a")); + assertTrue(trie.containsNode("way")); + assertTrue(trie.containsNode("of")); + assertTrue(trie.containsNode("life")); + } + + @Test + public void givenATrie_whenLookingForNonExistingElement_thenReturnsFalse() { + Trie trie = createExampleTrie(); + + assertFalse(trie.containsNode("99")); + } + + @Test + public void givenATrie_whenDeletingElements_thenTreeDoesNotContainThoseElements() { + + Trie trie = createExampleTrie(); + + assertTrue(trie.containsNode("Programming")); + trie.delete("Programming"); + assertFalse(trie.containsNode("Programming")); + } + + private Trie createExampleTrie() { + Trie trie = new Trie(); + + trie.insert("Programming"); + trie.insert("is"); + trie.insert("a"); + trie.insert("way"); + trie.insert("of"); + trie.insert("life"); + + return trie; + } +}