9. Heaps¶
The word heap is used in a couple of different contexts in Computer Science. A heap sometimes refers to an area of memory used for dynamic (i.e. run-time) memory allocation. Another meaning, and the topic of this chapter, is a data structure that is conceptually a complete binary tree. Heaps are used in implementing priority queues, the heapsort algorithm, and some graph algorithms. Heaps are somewhat like binary search trees in that they maintain an ordering of the items within the tree. However, a heap does not maintain a complete ordering of its items. This has some implications for how a heap may be used.
9.1. Heap Program¶
Here you can download
a starter shell for the heap implementation described in the chapter.
To run this program you must also download
the person.py file. Place both modules in the same directory. The heap.py program file contains a main function to test your heap implementation.
This heap program can be modified to support a different number of children. For instance, a four child heap is also possible. The file defaults to a three child heap.
1
2'''
3 File: heap.py
4 Author:
5 Date:
6 Description: This module provides the class Heap. We can create heaps which
7 are either largest-on-top or smallest-on-top. We can also create heaps
8 with a maximum number of children of our choice. As written, the default
9 number of children is 3 and the default initial capacity is 5. These
10 parameters can be changed by the way we invoke the class constructor.
11
12 The module also provides the efficient heap sort method. By default, the
13 methods sorts objects in increasing order. But we can also sort objects
14 in decreasing order.
15
16 Our implementation works for objects of any class that understand the
17 relational operators.
18
19'''
20
21testing = False
22from person import Person
23import math
24
25def heapSort(aSequence, increasingOrder = True):
26 ''' This method will answer a list of the elements of aSequence, which
27 by default will be sorted in increasing order. To sort in decreasing
28 order, send a second parameter which is False.
29 '''
30 # Do last, after buildFrom() and siftDownFrom(), other methods.
31 # More code needed!
32 return h.data[:]
33
34
35class Heap:
36 '''
37 The class Heap provides a generic heap abstract data type.
38 The instances of this class can hold objects of any sort that
39 understand the relational operators. It also allows us to create
40 heaps with any maximum number of children.
41 '''
42
43 DefaultCapacity = 5 # A class variable
44 DefaultNumberOfChildren = 3 # Another class variable
45
46 def __init__(self, capacity = DefaultCapacity,
47 largestOnTop = True, numberOfChildren =
48 DefaultNumberOfChildren):
49 self.size = 0
50 self.capacity = capacity
51 self.largestOnTop = largestOnTop
52 self.data = [None]*capacity
53 self.maxChildren = numberOfChildren
54
55 def __str__(self):
56 if self.largestOnTop:
57 sortOfHeap = 'largest on top'
58 else:
59 sortOfHeap = 'smallest on top'
60 st = 'It is a ' + sortOfHeap + ' heap:\n'
61 # .......
62 return st
63
64 def addToHeap(self,newObject):
65 '''If the heap is full, double its current capacity.
66 Add the newObject to the heap, maintaining it as a
67 heap of the same type. Answer newObject.
68 '''
69 pass # Allows compilation of file. Replace with actual code.
70
71 def bestChildOf(self, index, lastIndex):
72 ''' Answer the index of the "best child" of self.data[index], if it
73 exists. If not, answer None. lastIndex is the index of the last
74 object in the heap. For a largest on top heap, the best child is the
75 largest child. For a smallest on top heap, it is the smallest child
76 of the node with the given index.
77 '''
78 bestChild = None
79 # .......
80 return bestChild
81
82 def buildFrom(self, aSequence):
83 '''aSequence is an instance of a sequence collection which
84 understands the comparison operators. The elements of
85 aSequence are copied into the heap and ordered to build
86 a heap. '''
87 pass
88
89 def removeTop(self):
90 ''' If the heap is not empty, remove the top element
91 of the heap and adjust the heap accordingly. Answer the object
92 removed. If the heap is empty, return None.
93 '''
94 pass
95
96 def siftDownFrom( self, fromIndex ):
97 '''fromIndex is the index of an element in the heap.
98 Pre: data[fromIndex..size-1] satisfies the heap condition,
99 except perhaps for the element self.data[fromIndex].
100 Post: That element is sifted down as far as neccessary to
101 maintain the heap structure for data[fromIndex..size-1].
102 '''
103 pass
104
105 def __siftUpFrom(self, child):
106 ''' child is the index of a node in the heap. This method sifts
107 that node up as far as necessary to ensure that the path to the root
108 satisfies the heap condition. '''
109 pass
110
111 def __siftDownFromTo(self, fromIndex, lastIndex):
112 '''fromIndex is the index of an element in the heap.
113 Pre: data[fromIndex..lastIndex] satisfies the heap condition,
114 except perhaps for the element data[fromIndex].
115 Post: That element is sifted down as far as neccessary to
116 maintain the heap structure for data[fromIndex..lastIndex].'''
117 pass
118
119 def levelByLevelString(self):
120 ''' Return a string which lists the contents of the heap
121 level by level.
122 '''
123 index = 0 # start at the root node
124 maxLevel = \
125 math.ceil(math.log(self.size*(self.numberOfChildren - 1) + 1)/
126 math.log(self.numberOfChildren))
127 # MORE!
128
129 # Other methods?
130 # Use Doc strings for all methods!
131
132def main():
133 print("My name is ")
134 h = Heap()
135 h.addToHeap(20)
136 h.addToHeap(40)
137 h.addToHeap(-10)
138 h.addToHeap(72)
139 h.addToHeap(84)
140 h.addToHeap(-100)
141 h.addToHeap(54)
142 h.addToHeap(66)
143 h.addToHeap(99)
144 h.addToHeap(1000)
145 h.addToHeap(900)
146 print(h)
147
148 h.data[0] = 50
149 h.siftDownFrom(0)
150 print(h)
151
152 h.data[0] = 60
153 h.siftDownFrom(0)
154 print(h)
155
156 h = Heap(3, False)
157 h.buildFrom((20,40,-10, 72, 84, -100, 54,66, 99))
158 print(h)
159
160 theList = heapSort([10, 30, -100, 50, 20, 30, -40,70, 5, 50])
161 print(theList)
162
163 theList = heapSort([10, 30, -100, 50, 20, 30, -40,70, 5, 50], False)
164 print(theList)
165
166 print( "\nThe following is the extra output that happens when we" )
167 print( " create a heap that can have 5 children per node. \n" )
168 heap = Heap(numberOfChildren = 5)
169 heap.buildFrom((10, 20, -29, 16, 70, 30, 20, 100, 38, -293, \
170 77, -19, -77, 230, 91, -230, -48, 23))
171 print(heap)
172
173 a = heapSort((10, 20, -29, 16, 70, 30, 20, 100, 38, -293, \
174 77, -19, -77, 230, 91, -230, -48, 23))
175 print(a)
176
177
178 # Extra stuff to test removeTop()
179 h = Heap()
180 h.addToHeap(20)
181 h.addToHeap(40)
182 h.addToHeap(-10)
183 h.addToHeap(72)
184 h.addToHeap(84)
185 h.addToHeap(-100)
186 h.addToHeap(54)
187 h.addToHeap(66)
188 h.addToHeap(99)
189 h.addToHeap(1000)
190 h.addToHeap(900)
191 print(h)
192
193 print(h.removeTop())
194 print(h)
195
196 print( "trying heapSort method:" )
197 print( heapSort((20, -30, 45, 921, 37, 200, -1000, 4000, 57)) )
198 print( heapSort((20, -30, 45, 921, 37, 200, -1000, 4000, 57), False))
199 joe = Person('Joe', 99)
200 jill = Person('Jill', 200)
201 walt = Person('Walter', 3000)
202 dave = Person('David', 23)
203 kent = Person('Kent', 220)
204 alan = Person('Al', 110)
205 folks = [joe, jill, walt, dave, kent, alan]
206 print( heapSort(folks) )
207 print( heapSort(folks, False ))
208
209 h = Heap()
210 h.addToHeap(20)
211 h.addToHeap(40)
212 h.addToHeap(-10)
213 h.addToHeap(72)
214 h.addToHeap(84)
215 h.addToHeap(-100)
216 h.addToHeap(54)
217 h.addToHeap(66)
218 h.addToHeap(99)
219 h.addToHeap(1000)
220 h.addToHeap(900)
221 print()
222 print( 'A level by level listing of the heap:' )
223 print( h.levelByLevelString() )
224
225
226if __name__ == '__main__': main()
227
228''' The following is the output from running this code:
229My name is YOUR NAME
230[evaluate heap.py]
231It is a largest on top heap:
232The size of the heap is 11.
233The capacity of the heap is 20.
234The elements of the heap are:
2351000
23672
23799
238900
23920
240-100
24154
242-10
24366
24484
24540
246
247It is a largest on top heap:
248The size of the heap is 11.
249The capacity of the heap is 20.
250The elements of the heap are:
251900
25272
25399
25450
25520
256-100
25754
258-10
25966
26084
26140
262
263It is a largest on top heap:
264The size of the heap is 11.
265The capacity of the heap is 20.
266The elements of the heap are:
26799
26872
26984
27050
27120
272-100
27354
274-10
27566
27660
27740
278
279Output from buildFrom():
280It is a smallest on top heap:
281The size of the heap is 9.
282The capacity of the heap is 9.
283The elements of the heap are:
284-100
28520
286-10
28772
28884
28940
29054
29166
29299
293
294[-100, -40, 5, 10, 20, 30, 30, 50, 50, 70]
295[70, 50, 50, 30, 30, 20, 10, 5, -40, -100]
296
297The following is the extra output that happens when we
298 create a heap that can have 5 children per node.
299
300It is a largest on top heap:
301The size of the heap is 18.
302The capacity of the heap is 18.
303The elements of the heap are:
304230
305100
30691
30723
30870
30930
31020
31120
31238
313-293
31477
315-19
316-77
317-29
31810
319-230
320-48
32116
322
323[-293, -230, -77, -48, -29, -19, 10, 16, 20, 20, 23, 30, 38, 70, 77, 91, 100, 230]
324It is a largest on top heap:
325The size of the heap is 11.
326The capacity of the heap is 20.
327The elements of the heap are:
3281000
32972
33099
331900
33220
333-100
33454
335-10
33666
33784
33840
339
340Output from removeTop():
3411000
342It is a largest on top heap:
343The size of the heap is 10.
344The capacity of the heap is 20.
345The elements of the heap are:
346900
34772
34899
34940
35020
351-100
35254
353-10
35466
35584
356
357trying heapSort method:
358[-1000, -30, 20, 37, 45, 57, 200, 921, 4000]
359[4000, 921, 200, 57, 45, 37, 20, -30, -1000]
360[Name: David Id: 23 , Name: Joe Id: 99 , Name: Al Id: 110 ,
361 Name: Jill Id: 200 , Name: Kent Id: 220 , Name: Walter Id: 3000 ]
362[Name: Walter Id: 3000 , Name: Kent Id: 220 , Name: Jill Id: 200 ,
363 Name: Al Id: 110 , Name: Joe Id: 99 , Name: David Id: 23 ]
364
365A level by level listing of the heap:
366Level 1:
3671000
368
369Level 2:
37072
37199
372900
373
374Level 3:
37520
376-100
37754
378-10
37966
38084
38140
382
383'''