1
1
"""
2
- Binomial Heap
3
-
4
- Reference: Advanced Data Structures, Peter Brass
2
+ Binomial Heap
3
+ Reference: Advanced Data Structures, Peter Brass
5
4
"""
6
5
7
6
@@ -10,7 +9,7 @@ class Node:
10
9
Node in a doubly-linked binomial tree, containing:
11
10
- value
12
11
- size of left subtree
13
- - link to left, right and parent nodes
12
+ - link to left, right and parent nodes
14
13
"""
15
14
16
15
def __init__ (self , val ):
@@ -23,8 +22,8 @@ def __init__(self, val):
23
22
24
23
def mergeTrees (self , other ):
25
24
"""
26
- In-place merge of two binomial trees of equal size.
27
- Returns the root of the resulting tree
25
+ In-place merge of two binomial trees of equal size.
26
+ Returns the root of the resulting tree
28
27
"""
29
28
assert self .left_tree_size == other .left_tree_size , "Unequal Sizes of Blocks"
30
29
@@ -47,83 +46,79 @@ def mergeTrees(self, other):
47
46
48
47
49
48
class BinomialHeap :
50
- """
51
- Min-oriented priority queue implemented with the Binomial Heap data
52
- structure implemented with the BinomialHeap class. It supports:
53
-
49
+ r"""
50
+ Min-oriented priority queue implemented with the Binomial Heap data
51
+ structure implemented with the BinomialHeap class. It supports:
54
52
- Insert element in a heap with n elemnts: Guaranteed logn, amoratized 1
55
53
- Merge (meld) heaps of size m and n: O(logn + logm)
56
- - Delete Min: O(logn)
54
+ - Delete Min: O(logn)
57
55
- Peek (return min without deleting it): O(1)
58
-
59
- Example:
60
-
61
- Create a random permutation of 30 integers to be inserted and
62
- 19 of them deleted
63
- >>> import numpy as np
64
- >>> permutation = np.random.permutation(list(range(30)))
65
-
66
- Create a Heap and insert the 30 integers
67
-
68
- __init__() test
69
- >>> first_heap = BinomialHeap()
70
-
71
- 30 inserts - insert() test
72
- >>> for number in permutation:
73
- ... first_heap.insert(number)
74
-
75
- Size test
76
- >>> print(first_heap.size)
77
- 30
78
-
79
- Deleting - delete() test
80
- >>> for i in range(25):
81
- ... print(first_heap.deleteMin(), end=" ")
82
- 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
83
-
84
- Create a new Heap
85
- >>> second_heap = BinomialHeap()
86
- >>> vals = [17, 20, 31, 34]
87
- >>> for value in vals:
88
- ... second_heap.insert(value)
89
-
90
-
91
- The heap should have the following structure:
92
-
93
- 17
94
- / \
95
- # 31
96
- / \
97
- 20 34
98
- / \ / \
99
- # # # #
100
-
101
- preOrder() test
102
- >>> print(second_heap.preOrder())
103
- [(17, 0), ('#', 1), (31, 1), (20, 2), ('#', 3), ('#', 3), (34, 2), ('#', 3), ('#', 3)]
104
-
105
- printing Heap - __str__() test
106
- >>> print(second_heap)
107
- 17
108
- -#
109
- -31
110
- --20
111
- ---#
112
- ---#
113
- --34
114
- ---#
115
- ---#
116
-
117
- mergeHeaps() test
118
- >>> merged = second_heap.mergeHeaps(first_heap)
119
- >>> merged.peek()
120
- 17
121
-
122
- values in merged heap; (merge is inplace)
123
- >>> while not first_heap.isEmpty():
124
- ... print(first_heap.deleteMin(), end=" ")
125
- 17 20 25 26 27 28 29 31 34
126
-
56
+
57
+ Example:
58
+
59
+ Create a random permutation of 30 integers to be inserted and 19 of them deleted
60
+ >>> import numpy as np
61
+ >>> permutation = np.random.permutation(list(range(30)))
62
+
63
+ Create a Heap and insert the 30 integers
64
+ __init__() test
65
+ >>> first_heap = BinomialHeap()
66
+
67
+ 30 inserts - insert() test
68
+ >>> for number in permutation:
69
+ ... first_heap.insert(number)
70
+
71
+ Size test
72
+ >>> print(first_heap.size)
73
+ 30
74
+
75
+ Deleting - delete() test
76
+ >>> for i in range(25):
77
+ ... print(first_heap.deleteMin(), end=" ")
78
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
79
+
80
+ Create a new Heap
81
+ >>> second_heap = BinomialHeap()
82
+ >>> vals = [17, 20, 31, 34]
83
+ >>> for value in vals:
84
+ ... second_heap.insert(value)
85
+
86
+
87
+ The heap should have the following structure:
88
+
89
+ 17
90
+ / \
91
+ # 31
92
+ / \
93
+ 20 34
94
+ / \ / \
95
+ # # # #
96
+
97
+ preOrder() test
98
+ >>> print(second_heap.preOrder())
99
+ [(17, 0), ('#', 1), (31, 1), (20, 2), ('#', 3), ('#', 3), (34, 2), ('#', 3), ('#', 3)]
100
+
101
+ printing Heap - __str__() test
102
+ >>> print(second_heap)
103
+ 17
104
+ -#
105
+ -31
106
+ --20
107
+ ---#
108
+ ---#
109
+ --34
110
+ ---#
111
+ ---#
112
+
113
+ mergeHeaps() test
114
+ >>> merged = second_heap.mergeHeaps(first_heap)
115
+ >>> merged.peek()
116
+ 17
117
+
118
+ values in merged heap; (merge is inplace)
119
+ >>> while not first_heap.isEmpty():
120
+ ... print(first_heap.deleteMin(), end=" ")
121
+ 17 20 25 26 27 28 29 31 34
127
122
"""
128
123
129
124
def __init__ (self , bottom_root = None , min_node = None , heap_size = 0 ):
@@ -133,8 +128,8 @@ def __init__(self, bottom_root=None, min_node=None, heap_size=0):
133
128
134
129
def mergeHeaps (self , other ):
135
130
"""
136
- In-place merge of two binomial heaps.
137
- Both of them become the resulting merged heap
131
+ In-place merge of two binomial heaps.
132
+ Both of them become the resulting merged heap
138
133
"""
139
134
140
135
# Empty heaps corner cases
@@ -209,7 +204,7 @@ def mergeHeaps(self, other):
209
204
210
205
def insert (self , val ):
211
206
"""
212
- insert a value in the heap
207
+ insert a value in the heap
213
208
"""
214
209
if self .size == 0 :
215
210
self .bottom_root = Node (val )
@@ -251,7 +246,7 @@ def insert(self, val):
251
246
252
247
def peek (self ):
253
248
"""
254
- return min element without deleting it
249
+ return min element without deleting it
255
250
"""
256
251
return self .min_node .val
257
252
@@ -260,7 +255,7 @@ def isEmpty(self):
260
255
261
256
def deleteMin (self ):
262
257
"""
263
- delete min element and return it
258
+ delete min element and return it
264
259
"""
265
260
# assert not self.isEmpty(), "Empty Heap"
266
261
@@ -363,9 +358,9 @@ def deleteMin(self):
363
358
364
359
def preOrder (self ):
365
360
"""
366
- Returns the Pre-order representation of the heap including
367
- values of nodes plus their level distance from the root;
368
- Empty nodes appear as #
361
+ Returns the Pre-order representation of the heap including
362
+ values of nodes plus their level distance from the root;
363
+ Empty nodes appear as #
369
364
"""
370
365
# Find top root
371
366
top_root = self .bottom_root
@@ -378,7 +373,7 @@ def preOrder(self):
378
373
379
374
def __traversal (self , curr_node , preorder , level = 0 ):
380
375
"""
381
- Pre-order traversal of nodes
376
+ Pre-order traversal of nodes
382
377
"""
383
378
if curr_node :
384
379
preorder .append ((curr_node .val , level ))
@@ -389,8 +384,8 @@ def __traversal(self, curr_node, preorder, level=0):
389
384
390
385
def __str__ (self ):
391
386
"""
392
- Overwriting str for a pre-order print of nodes in heap;
393
- Performance is poor, so use only for small examples
387
+ Overwriting str for a pre-order print of nodes in heap;
388
+ Performance is poor, so use only for small examples
394
389
"""
395
390
if self .isEmpty ():
396
391
return ""
0 commit comments