class Median(object): def __init__(self, lst=[]): self.minHeap = PriorityQueue() self.maxHeap = MaxHeap() self.size = len(lst) if lst: lst = sorted(lst) mid = len(lst) // 2 self.minHeap = PriorityQueue(lst[mid:]) self.maxHeap = MaxHeap(lst[0:mid]) def get_median(self): if self.size == 0: raise IndexError("empty heap") if self.size == 1 or self.size % 2 != 0: return self.minHeap.get_min()[0] else: return self.maxHeap.get_max()[0] def insert(self, prio, ele): if self.size == 0: self.minHeap.insert(prio, ele) elif self.size == 1: self.minHeap.insert(prio, ele) prio, ele = self.minHeap.delete_min() self.maxHeap.insert(prio, ele) else: min_in_minHeap = self.minHeap.get_min()[0] max_in_maxHeap = self.maxHeap.get_max()[1] if prio >= min_in_minHeap: self.minHeap.insert(prio, ele) else: self.maxHeap.insert(prio, ele) if not self.is_balanced(): self.balance() self.size += 1 def is_balanced(self): return self.minHeap.size() <= self.maxHeap.size() + 1 and \ self.minHeap.size() >= self.maxHeap.size() def balance(self): while not self.is_balanced(): if self.minHeap.size() >= self.maxHeap.size() + 1: prio, ele = self.minHeap.delete_min() self.maxHeap.insert(prio, ele) else: prio, ele = self.maxHeap.delete_max() self.minHeap.insert(prio, ele)
def get_huffman_tree(frequency_lst): frequency_lst = Counter(s) pq = PriorityQueue() for char, freq in frequency_lst: pq.insert(freq, TreeNode(char)) while pq.size() > 1: freq1, node1 = pq.delete_min() freq2, node2 = pq.delete_min() internal_node = TreeNode(node1.val + node2.val, node1, node2) pq.insert(freq1 + freq2, internal_node) _, root = pq.delete_min() return get_code(root)
def dijkstra(graph, start): prev = {} costs = {} costs[start] = 0 visited = set() pq = PriorityQueue() for node in graph.nodes(): if node != -1: pq.insert(float('inf'), node) pq.insert(0, start) while not pq.is_empty(): cost, ele = pq.delete_min() visited.add(ele) for successor in graph.get_successors(ele): new_cost = cost + graph.get_cost(ele, successor) if successor not in visited and (successor not in costs or new_cost < costs[successor]): costs[successor] = new_cost prev[successor] = ele pq.update(new_cost, successor) res = {} for key in costs: res[(start, key)] = costs[key] return res
def prim(graph, start): # heap to have the vertex that are not added # key is the cheapest edge edge = set() overall_cost = 0 prev = {} prev[start] = start costs = {} costs[start] = 0 pq = PriorityQueue() visited = set() for node in graph.nodes(): pq.insert(float('inf'), node) pq.insert(0, start) while not pq.is_empty(): cost, ele = pq.delete_min() edge.add((prev[ele], ele)) overall_cost += cost visited.add(ele) for successor, edge_cost in graph.get_successors(ele): new_cost = edge_cost if successor not in visited and (successor not in costs or new_cost < costs[successor]): costs[successor] = new_cost prev[successor] = ele pq.update(new_cost, successor) return edge, overall_cost
class MaxHeap(object): def __init__(self, lst=[]): lst = [(-prio, ele) for (prio, ele) in lst] self.maxHeap = PriorityQueue(lst) def insert(self, priority, ele): self.maxHeap.insert(-priority, ele) def delete_max(self): prio, ele = self.maxHeap.delete_min() return -prio, ele def get_max(self): prio, ele = self.maxHeap.get_min() return -prio, ele def size(self): return self.maxHeap.size()
def dijkstra(graph, start): prev = {} costs = {} costs[start] = 0 pq = PriorityQueue() for node in graph.nodes(): pq.insert(float('inf'), node) pq.insert(0, start) while not pq.is_empty(): cost, ele = pq.delete_min() for successor, edge_cost in graph.get_successors(ele): new_cost = cost + edge_cost if successor not in costs or new_cost < costs[successor]: costs[successor] = new_cost prev[successor] = ele pq.update(new_cost, successor) return prev, costs