def __init__(self, capacity: int): if capacity % 2 == 0: self.left = MaxHeap(capacity) self.right = MinHeap(capacity) else: self.left = MaxHeap(capacity + 1) self.right = MinHeap(capacity + 1)
class MedianPriorityQueue: def __init__(self, capacity: int): if capacity % 2 == 0: self.left = MaxHeap(capacity) self.right = MinHeap(capacity) else: self.left = MaxHeap(capacity + 1) self.right = MinHeap(capacity + 1) def add(self, data: int): if self.left.size == 0 and self.right.size == 0: self.left.insert(data) elif self.right.size == 0: self.right.insert(data) elif data > self.right.get_min(): self.right.insert(data) else: self.left.insert(data) self.balance() def balance(self): if self.left.size - self.right.size >= 2: self.right.insert(self.left.remove_max()) elif self.right.size - self.left.size >= 2: self.left.insert(self.right.remove_min()) def remove(self): if self.left.size == 0: raise Exception("Priority Queue empty") if self.left.size >= self.right.size: data = self.left.remove_max() else: data = self.right.remove_min() self.balance() return data def peek(self): if self.left.size == 0 and self.right.size == 0: raise Exception("Priority Queue empty") if self.left.size >= self.right.size: return self.left.get_max() else: return self.right.get_min() def size(self): return self.left.size + self.right.size
def merge_k_sorted_lists(arrays: list): k = len(arrays) pointer = [0] * k heap = MinHeap(k) helper_hash = dict() for idx, value in enumerate(pointer): data = arrays[idx][value] helper_hash[data] = idx heap.insert(data) merged_array = [] while heap.size != 0: removed_data = heap.remove_min() idx = helper_hash[removed_data] pointer[idx] += 1 if pointer[idx] < len(arrays[idx]): data = arrays[idx][pointer[idx]] helper_hash[data] = idx heap.insert(data) helper_hash.pop(removed_data) merged_array.append(removed_data) return merged_array
def k_largest(array: list, k: int): heap = MinHeap(4) i = 0 while i < k: heap.insert(array[i]) i += 1 n = len(array) while i < n: if heap.get_min() < array[i]: heap.remove_min() heap.insert(array[i]) i += 1 return heap.storage
def prims(self): visited = [False] * len(self.graph) q = PriorityQueue(len(self.graph)) q.insert(Pair(vertex=0, acquired_vertex=-1, weight=0)) while q.size: removed = q.remove_min() if visited[removed.vertex]: continue visited[removed.vertex] = True if removed.acquired_vertex != -1: print( f"[{removed.vertex}-{removed.acquired_vertex}@{removed.weight}]" ) for edge in self.graph[removed.vertex]: if not visited[edge.nbr]: q.insert( Pair( vertex=edge.nbr, acquired_vertex=removed.vertex, weight=edge.weight, ))
def sort_k_nearly_sorted(array: list, k: int): heap = MinHeap(k + 1) i = 0 while i < k + 1: heap.insert(array[i]) i += 1 j = 0 n = len(array) while j < len(array): array[j] = heap.remove_min() j += 1 if i < n: heap.insert(array[i]) i += 1 return array
def dijkstras_algo(self, vertices: int, source: int): visited = [False] * len(self.graph) q = PriorityQueue(vertices) q.insert(Pair(vertex=source, psf=f"{source}", cost=0)) while q.size: removed = q.remove_min() if visited[removed.vertex]: continue visited[removed.vertex] = True print(f"{removed.vertex} via {removed.psf} @ {removed.cost}") for edge in self.graph[removed.vertex]: if not visited[edge.nbr]: q.insert( Pair( vertex=edge.nbr, psf=f"{removed.psf}{edge.nbr}", cost=removed.cost + edge.weight, ))