1
1
"""
2
2
A Trie/Prefix Tree is a kind of search tree used to provide quick lookup
3
3
of words/patterns in a set of words. A basic Trie however has O(n^2) space complexity
4
- making it impractical in practice. It however provides O(max(search_string, length of longest word)) lookup
5
- time making it an optimal approach when space is not an issue.
6
-
4
+ making it impractical in practice. It however provides O(max(search_string, length of longest word))
5
+ lookup time making it an optimal approach when space is not an issue.
7
6
"""
8
7
9
8
@@ -12,7 +11,7 @@ def __init__(self):
12
11
self .nodes = dict () # Mapping from char to TrieNode
13
12
self .is_leaf = False
14
13
15
- def insert_many (self , words : [str ]): # noqa: E999 This syntax is Python 3 only
14
+ def insert_many (self , words : [str ]):
16
15
"""
17
16
Inserts a list of words into the Trie
18
17
:param words: list of string words
@@ -21,7 +20,7 @@ def insert_many(self, words: [str]): # noqa: E999 This syntax is Python 3 only
21
20
for word in words :
22
21
self .insert (word )
23
22
24
- def insert (self , word : str ): # noqa: E999 This syntax is Python 3 only
23
+ def insert (self , word : str ):
25
24
"""
26
25
Inserts a word into the Trie
27
26
:param word: word to be inserted
@@ -34,7 +33,7 @@ def insert(self, word: str): # noqa: E999 This syntax is Python 3 only
34
33
curr = curr .nodes [char ]
35
34
curr .is_leaf = True
36
35
37
- def find (self , word : str ) -> bool : # noqa: E999 This syntax is Python 3 only
36
+ def find (self , word : str ) -> bool :
38
37
"""
39
38
Tries to find word in a Trie
40
39
:param word: word to look for
@@ -47,29 +46,82 @@ def find(self, word: str) -> bool: # noqa: E999 This syntax is Python 3 only
47
46
curr = curr .nodes [char ]
48
47
return curr .is_leaf
49
48
49
+ def delete (self , word : str ):
50
+ """
51
+ Deletes a word in a Trie
52
+ :param word: word to delete
53
+ :return: None
54
+ """
50
55
51
- def print_words (node : TrieNode , word : str ): # noqa: E999 This syntax is Python 3 only
56
+ def _delete (curr : TrieNode , word : str , index : int ):
57
+ if index == len (word ):
58
+ # If word does not exist
59
+ if not curr .is_leaf :
60
+ return False
61
+ curr .is_leaf = False
62
+ return len (curr .nodes ) == 0
63
+ char = word [index ]
64
+ char_node = curr .nodes .get (char )
65
+ # If char not in current trie node
66
+ if not char_node :
67
+ return False
68
+ # Flag to check if node can be deleted
69
+ delete_curr = _delete (char_node , word , index + 1 )
70
+ if delete_curr :
71
+ del curr .nodes [char ]
72
+ return len (curr .nodes ) == 0
73
+ return delete_curr
74
+
75
+ _delete (self , word , 0 )
76
+
77
+
78
+ def print_words (node : TrieNode , word : str ):
52
79
"""
53
80
Prints all the words in a Trie
54
81
:param node: root node of Trie
55
82
:param word: Word variable should be empty at start
56
83
:return: None
57
84
"""
58
85
if node .is_leaf :
59
- print (word , end = ' ' )
86
+ print (word , end = " " )
60
87
61
88
for key , value in node .nodes .items ():
62
89
print_words (value , word + key )
63
90
64
91
65
- def test ():
66
- words = [ ' banana' , ' bananas' , ' bandana' , ' band' , ' apple' , ' all' , ' beast' ]
92
+ def test_trie ():
93
+ words = " banana bananas bandana band apple all beast" . split ()
67
94
root = TrieNode ()
68
95
root .insert_many (words )
69
- # print_words(root, '')
70
- assert root .find ('banana' )
71
- assert not root .find ('bandanas' )
72
- assert not root .find ('apps' )
73
- assert root .find ('apple' )
96
+ # print_words(root, "")
97
+ assert all (root .find (word ) for word in words )
98
+ assert root .find ("banana" )
99
+ assert not root .find ("bandanas" )
100
+ assert not root .find ("apps" )
101
+ assert root .find ("apple" )
102
+ assert root .find ("all" )
103
+ root .delete ("all" )
104
+ assert not root .find ("all" )
105
+ root .delete ("banana" )
106
+ assert not root .find ("banana" )
107
+ assert root .find ("bananas" )
108
+ return True
109
+
110
+
111
+ def print_results (msg : str , passes : bool ) -> None :
112
+ print (str (msg ), "works!" if passes else "doesn't work :(" )
113
+
114
+
115
+ def pytests ():
116
+ assert test_trie ()
117
+
118
+
119
+ def main ():
120
+ """
121
+ >>> pytests()
122
+ """
123
+ print_results ("Testing trie functionality" , test_trie ())
124
+
74
125
75
- test ()
126
+ if __name__ == "__main__" :
127
+ main ()
0 commit comments