5
5
6
6
__all__ = [
7
7
'BinaryHeap' ,
8
+ 'TernaryHeap' ,
9
+ 'DHeap' ,
8
10
'BinomialHeap'
9
11
]
10
12
@@ -14,9 +16,10 @@ class Heap(object):
14
16
"""
15
17
pass
16
18
17
- class BinaryHeap (Heap ):
19
+
20
+ class DHeap (Heap ):
18
21
"""
19
- Represents Binary Heap.
22
+ Represents D-ary Heap.
20
23
21
24
Parameters
22
25
==========
@@ -26,7 +29,6 @@ class BinaryHeap(Heap):
26
29
List/tuple of initial elements in Heap.
27
30
28
31
heap_property : str
29
- The property of binary heap.
30
32
If the key stored in each node is
31
33
either greater than or equal to
32
34
the keys in the node's children
@@ -41,8 +43,8 @@ class BinaryHeap(Heap):
41
43
Examples
42
44
========
43
45
44
- >>> from pydatastructs.trees.heaps import BinaryHeap
45
- >>> min_heap = BinaryHeap (heap_property="min")
46
+ >>> from pydatastructs.trees.heaps import DHeap
47
+ >>> min_heap = DHeap (heap_property="min", d=3 )
46
48
>>> min_heap.insert(1, 1)
47
49
>>> min_heap.insert(5, 5)
48
50
>>> min_heap.insert(7, 7)
@@ -52,7 +54,7 @@ class BinaryHeap(Heap):
52
54
>>> min_heap.extract().key
53
55
4
54
56
55
- >>> max_heap = BinaryHeap (heap_property='max')
57
+ >>> max_heap = DHeap (heap_property='max', d=2 )
56
58
>>> max_heap.insert(1, 1)
57
59
>>> max_heap.insert(5, 5)
58
60
>>> max_heap.insert(7, 7)
@@ -65,31 +67,32 @@ class BinaryHeap(Heap):
65
67
References
66
68
==========
67
69
68
- .. [1] https://en.m. wikipedia.org/wiki/Binary_heap
70
+ .. [1] https://en.wikipedia.org/wiki/D-ary_heap
69
71
"""
70
- __slots__ = ['_comp' , 'heap' , 'heap_property' , '_last_pos_filled' ]
72
+ __slots__ = ['_comp' , 'heap' , 'd' , ' heap_property' , '_last_pos_filled' ]
71
73
72
- def __new__ (cls , elements = None , heap_property = "min" ):
74
+ def __new__ (cls , elements = None , heap_property = "min" , d = 4 ):
73
75
obj = Heap .__new__ (cls )
74
76
obj .heap_property = heap_property
77
+ obj .d = d
75
78
if heap_property == "min" :
76
79
obj ._comp = lambda key_parent , key_child : key_parent <= key_child
77
80
elif heap_property == "max" :
78
81
obj ._comp = lambda key_parent , key_child : key_parent >= key_child
79
82
else :
80
83
raise ValueError ("%s is invalid heap property" % (heap_property ))
81
84
if elements is None :
82
- elements = []
85
+ elements = DynamicOneDimensionalArray ( TreeNode , 0 )
83
86
obj .heap = elements
84
- obj ._last_pos_filled = len ( elements ) - 1
87
+ obj ._last_pos_filled = obj . heap . _last_pos_filled
85
88
obj ._build ()
86
89
return obj
87
90
88
91
def _build (self ):
89
92
for i in range (self ._last_pos_filled + 1 ):
90
- self .heap [i ].left , self .heap [i ].right = \
91
- 2 * i + 1 , 2 * i + 2
92
- for i in range ((self ._last_pos_filled + 1 )// 2 , - 1 , - 1 ):
93
+ self .heap [i ]._leftmost , self .heap [i ]._rightmost = \
94
+ self . d * i + 1 , self . d * i + self . d
95
+ for i in range ((self ._last_pos_filled + 1 )// self . d , - 1 , - 1 ):
93
96
self ._heapify (i )
94
97
95
98
def _swap (self , idx1 , idx2 ):
@@ -103,23 +106,22 @@ def _swap(self, idx1, idx2):
103
106
def _heapify (self , i ):
104
107
while True :
105
108
target = i
106
- l = 2 * i + 1
107
- r = 2 * i + 2
109
+ l = self . d * i + 1
110
+ r = self . d * i + self . d
108
111
109
- if l <= self . _last_pos_filled :
110
- target = l if self ._comp ( self . heap [ l ]. key , self . heap [ target ]. key ) \
111
- else i
112
- if r <= self . _last_pos_filled :
113
- target = r if self . _comp ( self . heap [ r ]. key , self . heap [ target ]. key ) \
114
- else target
112
+ for j in range ( l , r + 1 ) :
113
+ if j <= self ._last_pos_filled :
114
+ target = j if self . _comp ( self . heap [ j ]. key , self . heap [ target ]. key ) \
115
+ else target
116
+ else :
117
+ break
115
118
116
119
if target != i :
117
120
self ._swap (target , i )
118
121
i = target
119
122
else :
120
123
break
121
124
122
-
123
125
def insert (self , key , data ):
124
126
"""
125
127
Insert a new element to the heap according to heap property.
@@ -141,10 +143,10 @@ def insert(self, key, data):
141
143
self .heap .append (new_node )
142
144
self ._last_pos_filled += 1
143
145
i = self ._last_pos_filled
144
- self .heap [i ].left , self .heap [i ].right = 2 * i + 1 , 2 * i + 2
146
+ self .heap [i ]._leftmost , self .heap [i ]._rightmost = self . d * i + 1 , self . d * i + self . d
145
147
146
148
while True :
147
- parent = (i - 1 )// 2
149
+ parent = (i - 1 )// self . d
148
150
if i == 0 or self ._comp (self .heap [parent ].key , self .heap [i ].key ):
149
151
break
150
152
else :
@@ -169,23 +171,143 @@ def extract(self):
169
171
else :
170
172
element_to_be_extracted = TreeNode (self .heap [0 ].key , self .heap [0 ].data )
171
173
self ._swap (0 , self ._last_pos_filled )
172
- self .heap [self ._last_pos_filled ] = TreeNode (float ('inf' ) if self .heap_property == 'min'
173
- else float ('-inf' ), None )
174
- self ._heapify (0 )
175
- self .heap .pop ()
174
+ self .heap .delete (self ._last_pos_filled )
176
175
self ._last_pos_filled -= 1
176
+ self ._heapify (0 )
177
177
return element_to_be_extracted
178
178
179
179
def __str__ (self ):
180
180
to_be_printed = ['' for i in range (self ._last_pos_filled + 1 )]
181
181
for i in range (self ._last_pos_filled + 1 ):
182
182
node = self .heap [i ]
183
- to_be_printed [i ] = (node .left if node .left <= self ._last_pos_filled else None ,
184
- node .key , node .data ,
185
- node .right if node .right <= self ._last_pos_filled else None )
183
+ if node ._leftmost <= self ._last_pos_filled :
184
+ if node ._rightmost <= self ._last_pos_filled :
185
+ children = [x for x in range (node ._leftmost , node ._rightmost + 1 )]
186
+ else :
187
+ children = [x for x in range (node ._leftmost , self ._last_pos_filled + 1 )]
188
+ else :
189
+ children = []
190
+ to_be_printed [i ] = (node .key , node .data , children )
186
191
return str (to_be_printed )
187
192
188
193
194
+ class BinaryHeap (DHeap ):
195
+ """
196
+ Represents Binary Heap.
197
+
198
+ Parameters
199
+ ==========
200
+
201
+ elements : list, tuple
202
+ Optional, by default 'None'.
203
+ List/tuple of initial elements in Heap.
204
+
205
+ heap_property : str
206
+ If the key stored in each node is
207
+ either greater than or equal to
208
+ the keys in the node's children
209
+ then pass 'max'.
210
+ If the key stored in each node is
211
+ either less than or equal to
212
+ the keys in the node's children
213
+ then pass 'min'.
214
+ By default, the heap property is
215
+ set to 'min'.
216
+
217
+ Examples
218
+ ========
219
+
220
+ >>> from pydatastructs.trees.heaps import BinaryHeap
221
+ >>> min_heap = BinaryHeap(heap_property="min")
222
+ >>> min_heap.insert(1, 1)
223
+ >>> min_heap.insert(5, 5)
224
+ >>> min_heap.insert(7, 7)
225
+ >>> min_heap.extract().key
226
+ 1
227
+ >>> min_heap.insert(4, 4)
228
+ >>> min_heap.extract().key
229
+ 4
230
+
231
+ >>> max_heap = BinaryHeap(heap_property='max')
232
+ >>> max_heap.insert(1, 1)
233
+ >>> max_heap.insert(5, 5)
234
+ >>> max_heap.insert(7, 7)
235
+ >>> max_heap.extract().key
236
+ 7
237
+ >>> max_heap.insert(6, 6)
238
+ >>> max_heap.extract().key
239
+ 6
240
+
241
+ References
242
+ ==========
243
+
244
+ .. [1] https://en.m.wikipedia.org/wiki/Binary_heap
245
+ """
246
+ def __new__ (cls , elements = None , heap_property = "min" ):
247
+ obj = DHeap .__new__ (cls , elements , heap_property , 2 )
248
+ return obj
249
+
250
+
251
+ class TernaryHeap (DHeap ):
252
+ """
253
+ Represents Ternary Heap.
254
+
255
+ Parameters
256
+ ==========
257
+
258
+ elements : list, tuple
259
+ Optional, by default 'None'.
260
+ List/tuple of initial elements in Heap.
261
+
262
+ heap_property : str
263
+ If the key stored in each node is
264
+ either greater than or equal to
265
+ the keys in the node's children
266
+ then pass 'max'.
267
+ If the key stored in each node is
268
+ either less than or equal to
269
+ the keys in the node's children
270
+ then pass 'min'.
271
+ By default, the heap property is
272
+ set to 'min'.
273
+
274
+ Examples
275
+ ========
276
+
277
+ >>> from pydatastructs.trees.heaps import TernaryHeap
278
+ >>> min_heap = TernaryHeap(heap_property="min")
279
+ >>> min_heap.insert(1, 1)
280
+ >>> min_heap.insert(5, 5)
281
+ >>> min_heap.insert(7, 7)
282
+ >>> min_heap.insert(3, 3)
283
+ >>> min_heap.extract().key
284
+ 1
285
+ >>> min_heap.insert(4, 4)
286
+ >>> min_heap.extract().key
287
+ 3
288
+
289
+ >>> max_heap = TernaryHeap(heap_property='max')
290
+ >>> max_heap.insert(1, 1)
291
+ >>> max_heap.insert(5, 5)
292
+ >>> max_heap.insert(7, 7)
293
+ >>> min_heap.insert(3, 3)
294
+ >>> max_heap.extract().key
295
+ 7
296
+ >>> max_heap.insert(6, 6)
297
+ >>> max_heap.extract().key
298
+ 6
299
+
300
+ References
301
+ ==========
302
+
303
+ .. [1] https://en.wikipedia.org/wiki/D-ary_heap
304
+ .. [2] https://ece.uwaterloo.ca/~dwharder/aads/Algorithms/d-ary_heaps/Ternary_heaps/
305
+ """
306
+ def __new__ (cls , elements = None , heap_property = "min" ):
307
+ obj = DHeap .__new__ (cls , elements , heap_property , 3 )
308
+ return obj
309
+
310
+
189
311
class BinomialHeap (Heap ):
190
312
"""
191
313
Represents binomial heap.
0 commit comments