-
Notifications
You must be signed in to change notification settings - Fork 1
/
trie.py
144 lines (116 loc) · 3 KB
/
trie.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# Python program for delete operation
# in a Trie
class TrieNode(object):
'''
Trie node class
'''
def __init__(self):
self.children = [None]*26
# non zero if leaf
self.value = 0
def leafNode(self):
'''
Check if node is leaf node or not
'''
return self.value != 0
def isItFreeNode(self):
'''
If node have no children then it is free
If node have children return False else True
'''
for c in self.children:
if c:return False
return True
class Trie(object):
'''
Trie data structure class
'''
def __init__(self):
self.root = self.getNode()
# keep count on number of keys
# inserted in trie
self.count = 0
def _Index(self,ch):
'''
private helper function
Converts key current character into index
use only 'a' through 'z' and lower case
'''
return ord(ch)-ord('a')
def getNode(self):
'''
Returns new trie node (initialized to NULLs)
'''
return TrieNode()
def insert(self,key):
'''
If not present, inserts key into trie
If the key is prefix of trie node,mark
it as leaf(non zero)
'''
length = len(key)
pCrawl = self.root
self.count += 1
for level in range(length):
index = self._Index(key[level])
if pCrawl.children[index]:
# skip current node
pCrawl = pCrawl.children[index]
else:
# add new node
pCrawl.children[index] = self.getNode()
pCrawl = pCrawl.children[index]
# mark last node as leaf (non zero)
pCrawl.value = self.count
def search(self, key):
'''
Search key in the trie
Returns true if key presents in trie, else false
'''
length = len(key)
pCrawl = self.root
for level in range(length):
index = self._Index(key[level])
if not pCrawl.children[index]:
return False
pCrawl = pCrawl.children[index]
return pCrawl != None and pCrawl.value != 0
def _deleteHelper(self,pNode,key,level,length):
'''
Helper function for deleting key from trie
'''
if pNode:
# Base case
if level == length:
if pNode.value:
# unmark leaf node
pNode.value = 0
# if empty, node to be deleted
return pNode.isItFreeNode()
# recursive case
else:
index = self._Index(key[level])
if self._deleteHelper(pNode.children[index], key, level+1, length):
# last node marked,delete it
del pNode.children[index]
# recursively climb up and delete
# eligible nodes
return (not pNode.leafNode() and pNode.isItFreeNode())
return False
def deleteKey(self,key):
'''
Delete key from trie
'''
length = len(key)
if length > 0:
self._deleteHelper(self.root,key,0,length)
def main():
keys = ["she","sells","sea","shore","the","by","sheer"]
trie = Trie()
for key in keys:
trie.insert(key)
trie.deleteKey(keys[0])
print("{} {}".format(keys[0], "Present in trie" if trie.search(keys[0]) else "Not present in trie"))
print("{} {}".format(keys[6], "Present in trie" if trie.search(keys[6]) else "Not present in trie"))
if __name__ == '__main__':
main()