def breadth_first_search(graph, root_node=None):
ordering = []<EOL>all_nodes = graph.get_all_node_ids()<EOL>if not all_nodes:<EOL><INDENT>return ordering<EOL><DEDENT>queue = deque()<EOL>discovered = defaultdict(lambda: False)<EOL>to_visit = set(all_nodes)<EOL>if root_node is None:<EOL><INDENT>root_node = all_nodes[<NUM_LIT:0>]<EOL><DEDENT>discovered[root_node] = True<EOL>queue.appendleft(root_node)<EOL>while True:<EOL><INDENT>while len(queue) > <NUM_LIT:0>:<EOL><INDENT>current_node = queue.pop()<EOL>ordering.append(current_node)<EOL>to_visit.remove(current_node)<EOL>for n in graph.neighbors(current_node):<EOL><INDENT>if not discovered[n]:<EOL><INDENT>discovered[n] = True<EOL>queue.appendleft(n)<EOL><DEDENT><DEDENT><DEDENT>if len(to_visit) > <NUM_LIT:0>:<EOL><INDENT>node = to_visit.pop()<EOL>to_visit.add(node)  <EOL>discovered[node] = True<EOL>queue.appendleft(node)<EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>return ordering<EOL>
Searches through the tree in a breadth-first fashion.
        If root_node is None, an arbitrary node will be used as the root.
        If root_node is not None, it will be used as the root for the search tree.
        Returns a list of nodes, in the order that they were reached.