-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathelementary_st.py
215 lines (158 loc) · 5.65 KB
/
elementary_st.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#################################
### Linked List Symbol Table. ###
#################################
class LinkedST:
firstNode = None
N = 0 # Size of the symbol table.
class _Node:
def __init__(self, key, value, nextNode):
self.key = key
self.value = value
self.nextNode = nextNode
# Associate value with key.
def put(self, key, value):
if (key == None):
raise TypeError('Cannot put key of type None.')
node = self.__get(key)
if node != None:
node.value = value
return
oldFirstNode = self.firstNode
self.firstNode = self._Node(key, value, oldFirstNode)
self.N += 1
# Return true if the symbol table is empty.
def isEmpty(self):
return self.firstNode == None
# Return the size of the symbol table.
def size(self):
return self.N
# Return value corresponding to given key, or None if no such key.
def get(self, key):
if (key == None):
raise TypeError('Cannot search for key of type None.')
node = self.__get(key)
if node == None:
return None
return node.value
# Return true if the symbol table has the given key.
def contains(self, key):
if (key == None):
raise TypeError('Cannot search for key of type None.')
return self.__get(key) != None
# Delete the value, key pair associated with the given key.
def delete(self, key):
if self.isEmpty():
raise RuntimeError('Cannot delete from empty symbol table.')
if self.firstNode.key == key:
oldFirstNode = self.firstNode
self.firstNode = self.firstNode.nextNode
oldFirstNode = None
return
currentNode = self.firstNode
currentNextNode = self.firstNode.nextNode
while (currentNextNode != None):
if currentNextNode.key == key:
currentNode.nextNode = currentNextNode.nextNode
currentNextNode = None
self.N -= 1
return
currentNode = currentNextNode
currentNextNode = currentNextNode.nextNode
raise RuntimeError('Key not in symbol table.')
###
### HELPER FUNCTIONS
###
def __get(self, key):
currentNode = self.firstNode
while (currentNode != None):
if currentNode.key == key:
return currentNode
currentNode = currentNode.nextNode
return None
###################################
### Binary Search Symbol Table. ###
###################################
class BinarySearchST:
# NOTE: The append() function not used to practise resizing array
# implementation.
keys = [None] * 2 # (Resizing)Array of the keys.
values = [None] * 2 # (Resizing)Array of the values(parallel to the keys).
N = 0 # Size.
# Associate value with key.
def put(self, key, value):
if (key == None):
raise TypeError('Cannot put key of type None.')
i = self.rank(key)
if i < self.N and self.keys[i] == key:
self.values[i] = value
return
if len(self.keys) == self.N:
self.__resize(2 * self.N)
for j in reversed(range(i + 1, self.N + 1)):
self.keys[j] = self.keys[j - 1]
self.values[j] = self.values[j - 1]
self.keys[i] = key
self.values[i] = value
self.N += 1
# Return true if the symbol table is empty.
def isEmpty(self):
return self.N == 0
# Return the size of the symbol table.
def size(self):
return self.N
# Return value corresponding to given key, or None if no such key.
def get(self, key):
if (key == None):
raise TypeError('Cannot search for key of type None.')
if self.isEmpty():
return None
i = self.rank(key)
if i < self.N and self.keys[i] == key:
return self.values[i]
return None
# Return true if the symbol table has the given key.
def contains(self, key):
if (key == None):
raise TypeError('Cannot search for key of type None.')
return self.get(key) != None
# Delete the value, key pair associated with the given key.
def delete(self, key):
if self.isEmpty():
raise RuntimeError('Cannot delete from empty symbol table.')
i = self.rank(key)
if self.keys[i] != key:
raise RuntimeError('Key not in symbol table.')
for j in range(i, self.N - 1):
self.keys[j] = self.keys[j + 1]
self.values[j] = self.values[j + 1]
self.keys[self.N - 1] = None
self.values[self.N - 1] = None
self.N -= 1
if self.N == len(self.keys) // 4:
self.__resize(len(self.keys) // 2)
# The number of keys in the tree less than the given key.
def rank(self, key):
if (key == None):
raise TypeError('Cannot return rank for key of type None.')
low = 0
high = self.N - 1
while (high >= low):
mid = low + (high - low) // 2
if key > self.keys[mid]:
low = mid + 1
elif key < self.keys[mid]:
high = mid - 1
else:
return mid
return low
###
### HELPER FUNCTIONS
###
def __resize(self, capacity):
keysCopy = [None] * capacity
valuesCopy = [None] * capacity
for i in range(self.N):
keysCopy[i] = self.keys[i]
valuesCopy[i] = self.values[i]
self.keys = keysCopy
self.values = valuesCopy