11from collections import defaultdict
22INFINITY = 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
59class FibHeapNode :
610"""
@@ -42,8 +46,12 @@ def print_tree(self, tabwidth = 0):
4246An 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()#
4755for childtree in self .children_generator ():
4856childtree .print_tree (tabwidth + 1 )
4957
@@ -128,7 +136,7 @@ def __root_list_generator(self):
128136
129137
130138def print_heap (self ):
131- print ("head and minnode" , self .head , self .min_node )
139+ print ("### head and minnode" , self .head , self .min_node )
132140for root in self .__root_list_generator ():
133141#print(root, '(', root.left, root.right, root.child,')')
134142root .print_tree ()
@@ -152,7 +160,7 @@ def __consolidate(self):
152160
153161def merging_trees (cur_root ):
154162other_root = self .degree_tree_map [cur_root .rank ]
155- #print(other_root)#
163+
156164
157165if other_root is None :
158166self .degree_tree_map [cur_root .rank ] = cur_root
@@ -170,49 +178,54 @@ def merging_trees(cur_root):
170178
171179merging_trees (combined_root )
172180
173- self .min_node = self .head
174-
175181for 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-
181182merging_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
184200def __attach (self , node1 , node2 ):
185201# Connecting node 1 and node 2 such that node 2 is at node 1's right side
186202node1 .right = node2
187203node2 .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.
191207tail_one , tail_two = head_one .left , head_two .left
192208self .__attach (tail_one , head_two )
193209self .__attach (tail_two , head_one )
194- if teststr != "silent" : self .print_heap ()
195210return head_one
196211
197212def extract_min (self ):
198213if not self .head :
199214raise IndexError ("Popping from an empty heap." )
200215
201216node_to_be_popped = self .min_node
217+
202218if node_to_be_popped .child :
203219# If the node to be popped has any children,
204220# Add them to the root list.
205221self .__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.
210223self .__remove_node (node_to_be_popped )
211224self .__consolidate ()
212225
213226return node_to_be_popped .ele
214227
215- def not_extract_min_test (mylist ):
228+ def extract_min_test (mylist ):
216229heap = FibHeap ()
217230
218231for i in mylist :
@@ -225,43 +238,21 @@ def not_extract_min_test(mylist):
225238heap .extract_min ()
226239heap .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
259247extract_min_test_1 = lambda : extract_min_test ([1 , 2 ])
260248extract_min_test_2 = lambda : extract_min_test ([1 , 2 , 3 , 4 ])
261249extract_min_test_3 = lambda : extract_min_test ([10 , 20 , 30 , 40 , 50 , 60 , 70 , 80 ])
262250extract_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
266257def _FibHeap__remove_node_test_1 ():
267258heap = FibHeap ()
0 commit comments