CIS 3223. Data Structures and Algorithms

Graphs (2)

 

3. Graph traversal

As in trees, to traverse a graph means to systematically (i.e., with respect to the graph structure) visit every vertex exactly once. In some books the same operation is called walk.

Traversal is often used for searching a path from one given vertex to another vertex: if the traversal process starting from the former reaches the latter, then there is a path. For this reason, in many books they are called "search", though accurately speaking a "search" method and a "traversal" method are different in their input/output and ending conditions.

There are two basic methods for traversing a graph: "breadth first" and "depth first". Intuitively speaking, both traversal methods visit vertices according to their distance to the starting point. Their difference is: breadth-first attempts to stay as close as possible, while depth-first attempts to move as far as possible.

As special cases, both of these traversal methods can be defined on trees. Breadth-first is a level-by-level traversal of a tree. Depth-first is the same as preorder traversal in a tree. What makes graph traversal more complicated than tree traversal is that in a graph the traversal algorithm must be able to avoid loops and repeated visits.

In implementation, both methods keep a "waiting list" for the vertices whose neighbors need to be visited. Initially, it contains only the starting point of the traversal. Each time after a vertex is visited, its unvisited neighbors are visited, then added into the waiting list. This process is repeated until the waiting list is empty. The waiting list in breadth-first traversal is a queue (FIFO), and in depth-first, a stack (LIFO). In the latter case, if recursion is used, the stack become implicit.

Algorithms: breadth first, depth first

Examples: breadth first, depth first

The above traversal methods work on directed graphs, too. For unconnected graph, an outer layer loop can be used to go through the connected subgraphs.

The time complexity of both traversal algorithms is O(|E|), or, if initialization is included, O(|E|+|V|).

 

4. Search in a maze

As a case study, breadth-first search can be used to find the shortest path in a maze.

The algorithm is as follows:

  1. Read in the number of vertices and create the graph object.
  2. Read in the edges and insert the edges into the graph.
  3. Call the breadthFirstSearch method with this graph and the start 
     vertex as its argument. The method returns the array parent.
  4. Start at v, the end vertex.
  5. while v is not -1
  6.     Push v into the stack.
  7.     Set v to parent[v].
  8. while the stack is not empty
  9.     Pop a vertex off the stack and output it.