Skip to content

Commit 3f5c255

Browse files
authored
add trie
1 parent 7757004 commit 3f5c255

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

pygorithm/data_structures/trie.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
class Node:
2+
def __init__(self, v, p=None, w=False):
3+
self.word = w #If the node represents the end of a word or not
4+
self.parent = p
5+
self.value = v
6+
self.children = {}
7+
8+
9+
class Trie:
10+
def __init__(self):
11+
self.root = Node('') #The root of the trie is always empty
12+
13+
def Insert(self, word):
14+
"""
15+
Insert word in the trie. Starting from the root, move down the trie
16+
following the path of characters in the word. If the nodes for the word
17+
characters end, add them. When the last char is added, mark it as a
18+
word-ending node.
19+
"""
20+
l = len(word)
21+
curr = self.root
22+
for i, c in enumerate(word):
23+
last = False
24+
if(i == l-1):
25+
#The last char of the word
26+
last = True
27+
28+
if(c not in curr.children):
29+
curr.children[c] = Node(c, curr, last)
30+
elif(last):
31+
#c already exists, but as it is the last char of word,
32+
#it should now be flagged as a word in the trie.
33+
curr.children[c].word = True
34+
35+
curr = curr.children[c]
36+
37+
def Search(self, word):
38+
"""
39+
Searches for given word in trie. We want to find the last node for the
40+
word. If we can't, then it means the word is not in the trie.
41+
"""
42+
if self.FindFinalNode(word):
43+
return True
44+
else:
45+
return False
46+
47+
def FindWords(self, prefix):
48+
"""
49+
Find all words with the given prefix
50+
"""
51+
v = self.FindFinalNode(prefix)
52+
wList = self.BuildWordList(v, prefix)
53+
if(v and v.word):
54+
#v exists and the prefix is itself a word; add it to the list.
55+
wList.append(prefix)
56+
57+
return wList
58+
59+
def FindFinalNode(self, word):
60+
"""
61+
Returns the last node in given word. The process goes like this:
62+
Start from the root. For every char in word, go down one level.
63+
If we can't go down a level, then the word doesn't exist.
64+
If we do, and the current char is the last char of the word and
65+
the node we are currently at is a word, then we have found the given
66+
word.
67+
"""
68+
curr = self.root
69+
l = len(word)
70+
71+
for i, c in enumerate(word):
72+
if(c not in curr.children):
73+
#There is no prefix of cWord + c
74+
return None
75+
76+
if(i == l-1):
77+
#Last char of word
78+
return curr.children[c]
79+
80+
curr = curr.children[c]
81+
82+
return None
83+
84+
def BuildWordList(self, v, cWord):
85+
"""
86+
Recursively builds the list of words.
87+
* v: Node to check
88+
* cWord : The word built up to v
89+
"""
90+
if(not v):
91+
return None
92+
93+
wList = []
94+
for i, k in v.children.items():
95+
tempWord = cWord + i
96+
97+
if(k.word):
98+
#If the iterated prefix is a word, add it to the list
99+
wList.append(tempWord)
100+
101+
#The list of words under tWord
102+
wList.extend(self.BuildWordList(k, tempWord))
103+
104+
return wList

0 commit comments

Comments
 (0)