Skip to content

Commit adca059

Browse files
committed
extract_min has been tested.
1 parent 22a2e33 commit adca059

File tree

1 file changed

+40
-49
lines changed

1 file changed

+40
-49
lines changed

FibHeap.py

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
from collections import defaultdict
22
INFINITY = float('inf')
3-
teststr = "loud"##
3+
teststr = "silent"## Remember to use global when you use this.
4+
def show(something):
5+
if teststr == "loud": print(something)
6+
def struc(something):
7+
if teststr == "loud": something.print_heap()
48

59
class FibHeapNode:
610
"""
@@ -42,8 +46,12 @@ def print_tree(self, tabwidth = 0):
4246
An asterisk after the value indicates that this node is marked
4347
"""
4448

45-
print(tabwidth*" ", self.ele, '*' if self.mark else '', sep = "")
46-
input()#
49+
if teststr == "silent":
50+
print(tabwidth*" ", self.ele, '*' if self.mark else '', sep = "")
51+
elif teststr == "loud":
52+
print(tabwidth*" ", end = " ")
53+
show((self.ele, id(self)))
54+
#input()#
4755
for childtree in self.children_generator():
4856
childtree.print_tree(tabwidth + 1)
4957

@@ -128,7 +136,7 @@ def __root_list_generator(self):
128136

129137

130138
def print_heap(self):
131-
print("head and minnode", self.head, self.min_node)
139+
print("### head and minnode", self.head, self.min_node)
132140
for root in self.__root_list_generator():
133141
#print(root, '(', root.left, root.right, root.child,')')
134142
root.print_tree()
@@ -152,7 +160,7 @@ def __consolidate(self):
152160

153161
def merging_trees(cur_root):
154162
other_root = self.degree_tree_map[cur_root.rank]
155-
#print(other_root)#
163+
156164

157165
if other_root is None:
158166
self.degree_tree_map[cur_root.rank] = cur_root
@@ -170,49 +178,54 @@ def merging_trees(cur_root):
170178

171179
merging_trees(combined_root)
172180

173-
self.min_node = self.head
174-
175181
for cur_root in self.__root_list_generator():
176-
# print(cur_root, self.head, end=" ")
177-
178-
if cur_root < self.min_node:
179-
self.min_node = cur_root
180-
181182
merging_trees(cur_root)
182183

184+
# Maybe this can be done earlier.
185+
try:
186+
roots_iter = filter(lambda node: node is not None, self.degree_tree_map.values())
187+
self.min_node = min(roots_iter)
188+
"""
189+
Note: This does not have to be the node of the first_occurence of the minimum ele
190+
since dictionaries are not ordered by their key.
191+
This means you could have a node with ele 4 as head and another node with ele 4 as tail
192+
and self.min_node could point to the latter.
193+
"""
194+
except ValueError as err:
195+
if str(err) == "min() arg is an empty sequence":
196+
self.min_node = None
197+
else:
198+
raise ValueError(err)
183199

184200
def __attach(self, node1, node2):
185201
# Connecting node 1 and node 2 such that node 2 is at node 1's right side
186202
node1.right = node2
187203
node2.left = node1
188204

189-
def __merge_lls(self, head_one, head_two, teststr = ""):
205+
def __merge_lls(self, head_one, head_two):
190206
# Merging two circular doubly linked lists and returning the new head.
191207
tail_one, tail_two = head_one.left, head_two.left
192208
self.__attach(tail_one, head_two)
193209
self.__attach(tail_two, head_one)
194-
if teststr != "silent": self.print_heap()
195210
return head_one
196211

197212
def extract_min(self):
198213
if not self.head:
199214
raise IndexError("Popping from an empty heap.")
200215

201216
node_to_be_popped = self.min_node
217+
202218
if node_to_be_popped.child:
203219
# If the node to be popped has any children,
204220
# Add them to the root list.
205221
self.__merge_lls(self.head, node_to_be_popped.child)
206222

207-
if teststr == "loud": self.print_heap()#
208-
209-
if node_to_be_popped is self.head: self.head = self.head.right # Test this.
210223
self.__remove_node(node_to_be_popped)
211224
self.__consolidate()
212225

213226
return node_to_be_popped.ele
214227

215-
def not_extract_min_test(mylist):
228+
def extract_min_test(mylist):
216229
heap = FibHeap()
217230

218231
for i in mylist:
@@ -225,43 +238,21 @@ def not_extract_min_test(mylist):
225238
heap.extract_min()
226239
heap.print_heap()
227240

228-
def extract_min_test(mylist):
229-
heap = FibHeap()
230-
231-
for i in mylist:
232-
heap.insert(i)
233-
#print("After all insertions:")
234-
#heap.print_heap()#
235-
236-
for x in range(4):
237-
# print(f"After {x + 1}th extraction:")
238-
heap.extract_min("silent")
239-
#print("after 4th ex")
240-
#heap.print_heap()
241-
print("during 5th ex")
242-
heap.extract_min("loud")
243-
print("after 5th ex")
244-
heap.print_heap()
245-
#heap.extract_min()
246-
"""
247-
After 4th extraction:
248-
head and minnode 4 4
249-
4
250-
7
251-
4
252-
4
253-
8
254-
8
255-
9
256-
10
257-
"""
241+
try: heap.extract_min()
242+
except IndexError as err:
243+
if str(err) == "Popping from an empty heap.":
244+
pass
245+
else: raise IndexError(err)
258246

259247
extract_min_test_1 = lambda: extract_min_test([1, 2])
260248
extract_min_test_2 = lambda: extract_min_test([1, 2, 3, 4])
261249
extract_min_test_3 = lambda: extract_min_test([10, 20, 30, 40, 50, 60, 70, 80])
262250
extract_min_test_4 = lambda: extract_min_test([8, 8, 2, 4, 1, 4, 2, 9, 10, 4, 2, 7])
251+
extract_min_test_5 = lambda: extract_min_test([10])
252+
extract_min_test_6 = lambda: extract_min_test([20, 10, 40, 28, 46, 10, 35, 26, 83, 18, 32, 46])
253+
extract_min_test_7 = lambda: extract_min_test([])
263254

264-
extract_min_test_4()
255+
extract_min_test_6()
265256

266257
def _FibHeap__remove_node_test_1():
267258
heap = FibHeap()

0 commit comments

Comments
 (0)