Skip to content

Implement Trie Data Structure #88

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 6 commits into from
47 changes: 47 additions & 0 deletions trie/test_trie.py
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

file level comment

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import unittest
from trie import Trie

class TestTrie(unittest.TestCase):
def setUp(self):
self.trie = Trie()

def test_insert_and_search(self):
words = ["apple", "app", "apricot", "banana"]
for word in words:
self.trie.insert(word)

for word in words:
self.assertTrue(self.trie.search(word))

self.assertFalse(self.trie.search("grape"))
self.assertFalse(self.trie.search("ap"))
Comment on lines +8 to +17
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test more


def test_delete(self):
words = ["apple", "app", "apricot", "banana"]
for word in words:
self.trie.insert(word)

self.assertTrue(self.trie.delete("apple"))
self.assertFalse(self.trie.search("apple"))
self.assertTrue(self.trie.search("app"))

self.assertTrue(self.trie.delete("banana"))
self.assertFalse(self.trie.search("banana"))

self.assertFalse(self.trie.delete("grape"))
Comment on lines +19 to +31
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test a little more


def test_empty_string(self):
self.trie.insert("")
self.assertTrue(self.trie.search(""))
self.assertTrue(self.trie.delete(""))
self.assertFalse(self.trie.search(""))
Comment on lines +33 to +37
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more!

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more..

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finally!


def test_long_word(self):
long_word = "a" * 1000
self.trie.insert(long_word)
self.assertTrue(self.trie.search(long_word))
self.assertTrue(self.trie.delete(long_word))
self.assertFalse(self.trie.search(long_word))

if __name__ == "__main__":
unittest.main()
100 changes: 100 additions & 0 deletions trie/trie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
class TrieNode:
def __init__(self):
self.children = {}
self.is_end_of_word = False

class Trie:
def __init__(self):
self.root = TrieNode()

def insert(self, word):
"""
Insert a word into the trie.
Time complexity: O(m), where m is the length of the word.
"""
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.is_end_of_word = True

def search(self, word):
"""
Search for a word in the trie.
Returns True if the word is found, False otherwise.
Time complexity: O(m), where m is the length of the word.
"""
node = self.root
for char in word:
if char not in node.children:
return False
node = node.children[char]
return node.is_end_of_word

def delete(self, word):
"""
Delete a word from the trie.
Returns True if the word was deleted, False if it wasn't found.
Time complexity: O(m), where m is the length of the word.
"""
if not word:
if self.root.is_end_of_word:
self.root.is_end_of_word = False
return True
return False

stack = [(self.root, 0)]
last_node_with_branch = None
last_index_with_branch = 0

while stack:
node, index = stack.pop()

if index == len(word):
if not node.is_end_of_word:
return False
node.is_end_of_word = False
break

char = word[index]
if char not in node.children:
return False

if len(node.children) > 1 or node.is_end_of_word:
last_node_with_branch = node
last_index_with_branch = index

stack.append((node.children[char], index + 1))

if not node.children:
if last_node_with_branch:
del last_node_with_branch.children[word[last_index_with_branch]]
else:
self.root.children.pop(word[0], None)

return True

# Example usage
if __name__ == "__main__":
trie = Trie()

# Insert words
words = ["apple", "app", "apricot", "banana"]
for word in words:
trie.insert(word)

# Search words
print(trie.search("apple")) # True
print(trie.search("app")) # True
print(trie.search("apricot")) # True
print(trie.search("banana")) # True
print(trie.search("grape")) # False

# Delete words
print(trie.delete("apple")) # True
print(trie.search("apple")) # False
print(trie.search("app")) # True

print(trie.delete("banana")) # True
print(trie.search("banana")) # False
Loading