def make_depth_lists(tree): """ Space: O(n) Time: O(n) :param tree: :return: """ if tree.rchild is None and tree.lchild is None: return None q = Queue() level = 0 q.enqueue((tree, level)) depth_lists = dict() while not q.is_empty(): node, level = q.dequeue() if depth_lists.get(level) is None: depth_lists[level] = Cons(node, None) else: depth_lists[level] = Cons(node, depth_lists[level]) if node.rchild is not None: q.enqueue((node.rchild, level + 1)) if node.lchild is not None: q.enqueue((node.lchild, level + 1)) return depth_lists
def BFS(graph, s): ''' Breadth-first search implementation: BFS is an algorithm for traversing or searching tree or graph data structures. It starts at the tree root and explores the neighbor nodes first, before moving to the next level neighbours. :param graph: the graph to be searched, nodes have to be integers :param s: the source node, where the search begins :return: ordered list of nodes of BFS traversal ''' if graph.count_nodes() == 0: return [] visited = [] bfs_trav = [] queue = Queue() queue.push(s) visited.append(s) while not queue.is_empty(): current = queue.pop() bfs_trav.append(current) print(current) for n in graph[current]: if n not in visited: print('node: {}'.format(n)) queue.push(n) visited.append(n) return bfs_trav
def a_to_b(n1, n2): q = Queue() visited = {n1} q.enqueue(n1) while not q.is_empty(): current = q.dequeue() if current == n2: return True for child in current.children: if child not in visited: visited.add(child) q.enqueue(child) return False
def sorted_merge(A: list, B: list): """ Time: O(A + B) actually O(2A + 2B), copying then reading back, with O(min(A, B)) comparisons in the worst case Space: O(n) :param A: :param B: :return: """ p1, p2 = 0, len(A) - len(B) stack_A = Queue(iterable=A[:p2]) stack_B = Queue(iterable=B) for i in range(len(A)): if stack_A.is_empty(): A[i] = stack_B.pop() elif stack_B.is_empty(): A[i] = stack_A.pop() elif stack_A.peek() <= stack_B.peek(): A[i] = stack_A.pop() else: A[i] = stack_B.pop() return A
def get_unique_adjacent(string: str) -> Optional[str]: length = len(string) freq = {} if length == 0: return string for i in range(length): if string[i] not in freq: freq[string[i]] = 0 freq[string[i]] += 1 sorted_freq = sorted(freq.items(), key=lambda x: x[1], reverse=True) queue = Queue() [queue.enqueue(item) for item in sorted_freq] result = "" if length % 2 == 0 and sorted_freq[0][1] > length // 2: return None elif length % 2 == 1 and sorted_freq[0][1] > (length // 2) + 1: return None while not queue.is_empty(): if len(queue) == 1: elem, freq = queue.peek() if freq == 2: result = elem + result + elem break elif freq == 1: if result[-1] != elem: result += elem else: result = elem + result break return None elem1, freq1 = queue.peek() elem2, freq2 = None, None if len(queue) > 1: elem2, freq2 = queue[1] result += elem1 + elem2 queue[0] = elem1, freq1 - 1 if len(queue) > 1: queue[1] = elem2, freq2 - 1 if len(queue) > 1 and queue[1][1] == 0: queue.dequeue() if len(queue) > 0 and queue[0][1] == 0: queue.dequeue() return result
def remove_island(matrix: Matrix, position: Position, grid_shape: GridShape) -> None: # using bfs to remove the islands queue = Queue() queue.enqueue(position) while not queue.is_empty(): curr_position = queue.dequeue() i, j = curr_position if matrix[i][j] == 1: matrix[i][j] = 0 for neighbour in get_neighbours((i, j), grid_shape): y, x = neighbour if matrix[y][x] == 1: queue.enqueue(neighbour)
def get_lvl_wise_nodes(tree: BinaryTree) -> List[Node]: # using bfs to generate the list of nodes by level if not tree.root: return [] queue = Queue() queue.enqueue(tree.root) ans = [] while not queue.is_empty(): node = queue.dequeue() if node.left is not None: queue.enqueue(node.left) if node.right is not None: queue.enqueue(node.right) ans.append(node.val) return ans
def is_subtree(T1, T2): """ :param T1: :param T2: :return: """ q = Queue() q.enqueue(T1) while not q.is_empty(): node = q.dequeue() if node.value == T2.value and treequal(node, T2): return True for child in node.children: q.enqueue(child) return False
def is_minimally_connected(graph: GraphUndirectedUnweighted) -> bool: graph_copy = GraphUndirectedUnweighted() graph_copy.connections, graph_copy.nodes = deepcopy(graph.connections), graph.nodes # getting a random node for starting the traversal for node in graph.connections: start = node break # running bfs and checking if a node is visited more than once # (redundant edges present => not a minimally connected graph) visited = set([start]) queue = Queue() queue.enqueue(start) while not queue.is_empty(): node = queue.dequeue() for neighbour in graph_copy.connections[node]: graph_copy.connections[neighbour].remove(node) queue.enqueue(neighbour) if neighbour in visited: return False visited.add(neighbour) return True
def bfs_path(graph: GraphUndirectedUnweighted, start: str, stop: str) -> List[str]: parent_map = {node: None for node in graph.connections} # bfs queue = Queue() seen = set() queue.enqueue(start) seen.add(start) while not queue.is_empty(): node = queue.dequeue() for neighbour in graph.connections[node]: if neighbour not in seen: parent_map[neighbour] = node queue.enqueue(neighbour) seen.add(neighbour) # generating the path path = [stop] while parent_map[path[-1]] is not None: path.append(parent_map[path[-1]]) if path[-1] == start: break return reversed(path)
def get_level_min_sum(tree: BinaryTree) -> int: if not tree.root: return 0 # the levels are delimited in the queue by None queue = Queue() queue.enqueue(tree.root) queue.enqueue(None) min_level_sum = maxsize curr_level_sum = 0 while not queue.is_empty(): node = queue.dequeue() if node is not None: if node.left: queue.enqueue(node.left) if node.right: queue.enqueue(node.right) curr_level_sum += node.val else: min_level_sum = min(curr_level_sum, min_level_sum) if len(queue) > 0: queue.enqueue(None) curr_level_sum = 0 return min_level_sum
def simulation( num_seconds:int, pages_per_minute:int): lab_printer = Printer( pages_per_minute ) print_queue = Queue() waiting_times = [] #loop through each second for current_second in range(num_seconds): #check if a print task has been created ## the code to check that ## generates a print task every 180 sec if new_print_task(): #print task created task = Task(current_second) #enqueue the atsk print_queue.enqueue(task) #check printer status # check if printer is busy # Check if print_queue is empty if ((not lab_printer.busy()) and (not print_queue.is_empty())): #printer is idle and tasks in queue #get next task from qeueue next_task = print_queue.dequeue() #calculate wait time i.e # current_time - task_created_time_stamp wait_time = next_task.wait_time( current_second ) #add to list to calculate average wait time waiting_times.append(wait_time) #start task # The printer now does one second of printing # also subtracts 1 second # from the time required for that task. lab_printer.start_next(next_task) #manage printer state # if no task ..set to idle lab_printer.tick() #calculate average wait time average_wait = \ sum( waiting_times ) / len(waiting_times) print( "Average Wait %6.2f secs %3d tasks remaining." \ %(average_wait, print_queue.size()) )