| 
 | 1 | +class Heap:  | 
 | 2 | + # max heap init data  | 
 | 3 | + def __init__(self):  | 
 | 4 | + self.data = []  | 
 | 5 | + | 
 | 6 | + # get parent index  | 
 | 7 | + @staticmethod  | 
 | 8 | + def _parent(idx):  | 
 | 9 | + return (idx-1)//2  | 
 | 10 | + | 
 | 11 | + # get left child index  | 
 | 12 | + @staticmethod  | 
 | 13 | + def _left(idx):  | 
 | 14 | + return 2*idx+1  | 
 | 15 | + | 
 | 16 | + # get right child index  | 
 | 17 | + @staticmethod  | 
 | 18 | + def _right(idx):  | 
 | 19 | + return 2*idx+2  | 
 | 20 | + | 
 | 21 | + # function to rearrange elements in array to heap  | 
 | 22 | + def _heapify(self, idx=0):  | 
 | 23 | + while True:  | 
 | 24 | + l = Heap._left(idx)  | 
 | 25 | + r = Heap._right(idx)  | 
 | 26 | + maxidx = idx  | 
 | 27 | + if l < len(self) and self.data[l] > self.data[idx]:  | 
 | 28 | + maxidx = l  | 
 | 29 | + if r < len(self) and self.data[r] > self.data[maxidx]:  | 
 | 30 | + maxidx = r  | 
 | 31 | + if maxidx != idx:  | 
 | 32 | + self.data[maxidx], self.data[idx] = self.data[idx], self.data[maxidx]  | 
 | 33 | + idx = maxidx  | 
 | 34 | + else:  | 
 | 35 | + break  | 
 | 36 | + | 
 | 37 | + # function to rearrange elements in array to heap (recursively)  | 
 | 38 | + def _heapify_rec(self, idx=0):  | 
 | 39 | + l = Heap._left(idx)  | 
 | 40 | + r = Heap._right(idx)  | 
 | 41 | + maxidx = idx  | 
 | 42 | + if l < len(self) and self.data[l] > self.data[idx]:  | 
 | 43 | + maxidx = l  | 
 | 44 | + if r < len(self) and self.data[r] > self.data[maxidx]:  | 
 | 45 | + maxidx = r  | 
 | 46 | + if maxidx != idx:  | 
 | 47 | + self.data[maxidx], self.data[idx] = self.data[idx], self.data[maxidx]  | 
 | 48 | + self._heapify_rec(maxidx)  | 
 | 49 | + | 
 | 50 | + # add element to the heap  | 
 | 51 | + def add(self, x):  | 
 | 52 | + self.data.append(x)  | 
 | 53 | + i = len(self.data) - 1  | 
 | 54 | + p = Heap._parent(i)  | 
 | 55 | + while i > 0 and self.data[p] < self.data[i]:  | 
 | 56 | + self.data[p], self.data[i] = self.data[i], self.data[p]  | 
 | 57 | + i = p  | 
 | 58 | + p = Heap._parent(i)  | 
 | 59 | + | 
 | 60 | + # return the maximum of the heap  | 
 | 61 | + def max(self):  | 
 | 62 | + return self.data[0]  | 
 | 63 | + | 
 | 64 | + # return and remove the maximum of the heap  | 
 | 65 | + def pop_max(self):  | 
 | 66 | + ret = self.data[0]  | 
 | 67 | + self.data[0] = self.data[len(self.data)-1]  | 
 | 68 | + del self.data[len(self.data)-1]  | 
 | 69 | + self._heapify()  | 
 | 70 | + return ret  | 
 | 71 | + | 
 | 72 | + # check if the heap is not empty  | 
 | 73 | + def __bool__(self):  | 
 | 74 | + return len(self.data) > 0  | 
 | 75 | + | 
 | 76 | + # return the length/size of the heap  | 
 | 77 | + def __len__(self):  | 
 | 78 | + return len(self.data)  | 
 | 79 | + | 
 | 80 | + # return data of the heap in string type  | 
 | 81 | + def __repr__(self):  | 
 | 82 | + return repr(self.data)  | 
 | 83 | + | 
 | 84 | +# tests for Heap class  | 
 | 85 | +if __name__ == "__main__":  | 
 | 86 | + import random  | 
 | 87 | + | 
 | 88 | + # create new Heap  | 
 | 89 | + h = Heap()  | 
 | 90 | + | 
 | 91 | + # add items to heap  | 
 | 92 | + for _ in range(30):  | 
 | 93 | + h.add(random.randrange(100))  | 
 | 94 | + | 
 | 95 | + # print heap  | 
 | 96 | + print("Heap: ", h)  | 
 | 97 | + | 
 | 98 | + # pop max  | 
 | 99 | + print("Pop max of heap: ", h.pop_max())  | 
 | 100 | + print("Heap after pop: ", h)  | 
0 commit comments