From 1bed5472267f2a7bb531ad391fe6e0dc34b10817 Mon Sep 17 00:00:00 2001 From: Javon Davis Date: Sun, 10 Sep 2017 13:10:33 -0500 Subject: [PATCH] Trie implementation (#111) * Started Trie implementation. * Basic definition of Trie in comments at the top of the file * Defined Trie class and method signatures. * * Renamed method signatures to match formal definitions * Finished Simple Trie implementation and added test functions * Finished function to insert a word into Trie * Finished function to find a word in the Trie * Added Test functions with Assertions * Updated test function to read from the Dictionary.txt file in repository * * No longer using $ to mark end of word * No longer reading from file but instead provided simple sample input for easier testing * Deleting empty __init__.py file --- data_structures/Trie/Trie.py | 75 ++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 data_structures/Trie/Trie.py diff --git a/data_structures/Trie/Trie.py b/data_structures/Trie/Trie.py new file mode 100644 index 000000000..7c886144d --- /dev/null +++ b/data_structures/Trie/Trie.py @@ -0,0 +1,75 @@ +""" +A Trie/Prefix Tree is a kind of search tree used to provide quick lookup +of words/patterns in a set of words. A basic Trie however has O(n^2) space complexity +making it impractical in practice. It however provides O(max(search_string, length of longest word)) lookup +time making it an optimal approach when space is not an issue. + +""" + + +class TrieNode: + def __init__(self): + self.nodes = dict() # Mapping from char to TrieNode + self.is_leaf = False + + def insert_many(self, words: [str]): + """ + Inserts a list of words into the Trie + :param words: list of string words + :return: None + """ + for word in words: + self.insert(word) + + def insert(self, word: str): + """ + Inserts a word into the Trie + :param word: word to be inserted + :return: None + """ + curr = self + for char in word: + if char not in curr.nodes: + curr.nodes[char] = TrieNode() + curr = curr.nodes[char] + curr.is_leaf = True + + def find(self, word: str) -> bool: + """ + Tries to find word in a Trie + :param word: word to look for + :return: Returns True if word is found, False otherwise + """ + curr = self + for char in word: + if char not in curr.nodes: + return False + curr = curr.nodes[char] + return curr.is_leaf + + +def print_words(node: TrieNode, word: str): + """ + Prints all the words in a Trie + :param node: root node of Trie + :param word: Word variable should be empty at start + :return: None + """ + if node.is_leaf: + print(word, end=' ') + + for key, value in node.nodes.items(): + print_words(value, word + key) + + +def test(): + words = ['banana', 'bananas', 'bandana', 'band', 'apple', 'all', 'beast'] + root = TrieNode() + root.insert_many(words) + # print_words(root, '') + assert root.find('banana') + assert not root.find('bandanas') + assert not root.find('apps') + assert root.find('apple') + +test()