def topological_sort_kahn(graph: Graph) -> list: """ Ex 22.4-5. If return list is shorter than graph vertex length, it means the topological sort cannot be performed. O(V + E) time. """ in_degrees = {} ret = [] for v_key in graph.vertex_keys(): in_degrees[v_key] = 0 for u_key in graph.vertex_keys(): for v_key, _ in graph.get_vertex(u_key).successors(): in_degrees[v_key] += 1 zero_in_degree_set = deque() for v_key in graph.vertex_keys(): if in_degrees[v_key] == 0: zero_in_degree_set.append(v_key) while zero_in_degree_set: u_key = zero_in_degree_set.popleft() ret.append(u_key) for v_key, _ in list(graph.get_vertex(u_key).successors()): graph.remove_edge(u_key, v_key) in_degrees[v_key] -= 1 if in_degrees[v_key] == 0: zero_in_degree_set.append(v_key) return ret
def _euler(graph: Graph, path: list, src_index: int) -> Tuple[list, int]: src_key = path[src_index] src = graph.get_vertex(src_key) u = src sub_path = [src_key] while u.successor_len > 0: v = None for v_key, _ in u.successors(): v = graph.get_vertex(v_key) break graph.remove_edge(u.key, v.key) graph.remove_edge(v.key, u.key) sub_path.append(v.key) u = v i = 1 while i < len(sub_path): sub_path, delta_len = _euler(graph, sub_path, i) i += delta_len path = path[0:src_index] + sub_path + path[src_index + 1:] return path, len(sub_path)