class PriorityQueue: def __init__(self, data = None): if data is None: self.__dim = 3 self.__heap = [None] * self.__dim self.__n = 1 # element in position 0 is not used. # _n is the first available position in _heap else: self.__dim = len(data)+1 self.__heap = [None] # starting dummy element self.__heap.extend(data) self.__n = self.__dim print(self) self.__make_heap() def is_empty(self): return self.__n == 1 def insert(self, val): if self.__n == self.__dim: self.__heap.extend([None] * self.__dim) self.__dim *= 2 self.__heap[self.__n] = val pos = self.__n self.__n += 1 while pos > 1 and self.__heap[pos//2] < val: self.__heap[pos], self.__heap[pos//2] = self.__heap[pos//2], self.__heap[pos] pos = pos // 2 def get_max(self): if self.__n == 1: return None else: return self.__heap[1] def pop_max(self): if self.__n == 1: return None else: max_val = self.__heap[1] self.__heap[1] = self.__heap[self.__n - 1] self.__n -= 1 self.__heapify(1) return max_val def __heapify(self, pos): left_child = 2 * pos right_child = 2 * pos + 1 largest = pos if left_child < self.__n and self.__heap[left_child] > self.__heap[pos]: largest = left_child if right_child < self.__n and self.__heap[right_child] > max(self.__heap[left_child], self.__heap[pos]): largest = right_child if largest != pos: self.__heap[pos], self.__heap[largest] = self.__heap[largest], self.__heap[pos] self.__heapify(largest) def __make_heap(self): # O(n) worst-case time complexity heap construction last_parent = (self.__n - 1) // 2 for p in range(last_parent, 0, -1): self.__heapify(p) def __str__(self): return f'{self.__n-1} elements: ' + str(self.__heap)