breadthFirstSearch = (graph, startVertex, callbacks) => {
  const vertexQueue = new Queue();
  vertexQueue.push(startVertex);
  callbacks = normalizeCallbacks(callbacks, [startVertex]);

  let vertex;
  const enqueue = neighbor => {
    if (callbacks.allowTraversal(vertex, neighbor)) {
      callbacks.onTraversal(vertex, neighbor);
      vertexQueue.push(neighbor);
    }
  };

  while (!vertexQueue.isEmpty()) {
    vertex = vertexQueue.pop();
    callbacks.enterVertex(vertex);
    graph.neighbors(vertex).forEach(enqueue);
    callbacks.leaveVertex(vertex);
  }
}
Run Breadth-First Search from a start vertex.
Complexity (default implementation): O(V + E).

@param {Graph} graph
@param {*} startVertex
@param {Callbacks} [callbacks]