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 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)