Graph

Graph

Graphs: Collection of distinct vertices and distinct edges.

Directed Graph: Graph where the edges are arrows.

Example: On Adjacency B \to A

Three Types of Graphs:

  1. Connected Graph: Has a path between every pair of distinct vertices (You can pick any two vertices and find a path between them)
  2. Complete: There is a path from every vertex to every other vertex.
  3. Disconnected: There is at least one pair of vertices with no edge connecting them.

Paths

Path: A path between two vertices is a sequence of edges.

Note: Directed Path

Note: Weighted Edges

Traversals

  1. Breadth-First (Level Order)

Example: Breadth-First Algorithm

Algorithm getBreadthFirstTraversal(originVertex) {
  traversalOrderQueue; // Holds result
  vertexQueue; // Holds vertices as they're visited
  while(!vertexQeuue.isEmpty()) {
      frontVertex = vertexQueue.dequeue();
      while (frontVertex has a neighbor) {
          nextNeighbor = next neighbor of frontVertex;
          if (nextNeighbor is not visited) {
              Mark nextNeighor as visited;
              traversalOrder.enqeue(nextNeighbor);
              vertexQeue.enqueue(nextNeighbor);
          }
      }
  }
  return traversalOrderQueue;
}
  1. Depth-First (Pre-order)

Example: Depth-First Algorithm


Algorithm 

Note: Finding Neighbors

Topological Order

Directed Acyclic Graph (DAC): Directed graph without cycles

Example: Topological Sort Algorithm

Algorithm getTopologicalOrder() {
  vertexStack = stack to hold verticies as they're visited;
  numberOfVertices = number of vertices on the stack;
  for (counter = 1 to numberOfVertices) {
      nextVertex = anunvisited vertex whose neighbors, if any, are all visited
      Mark nextVertex as visited
      vertexStack.push(nextVertex)
  }
  return vertexStack;
}

Real-World Example: Project Management

Shortest Path

Note: Unweighted Graph

Data Structure for Vertices:

  1. Vertex Label
  2. Path Length
  3. Predecessor

Data Structure for Paths:

Example: Algorithm to get shortest path of unweighted graph

Algorithm getShortestPath(originVertex, endVertex, path) {
  done = false;
  vertexQueue;
  Mark originVertex as visited
  // Traverse (kinda like breadth-first_
  while (!done && frontVettex has a neighbor) {
      nextNeighbor = next neighbor of frontVertex;
      if (nextNeighbor is not visited) {
          Mark nextNeighbor as visited
          Set the length of the path to nextNeighbor to 1 + ength of path to frontVertex
          Set the predecessor of nextNeighbor to frontVertex
          vertexQueue.enqueue(nextNeighbor);
      }
      if (nextNeighbor equals endVertex) {
          done = true;
      }
  }
  // Construct shortest path
  pathLength = length of path to endVertex
  path.push(endVertex);
  vertex = endVertex;
  while (vertex has a predecessor) {
      vertex = predecessor of vertex;
      path.push(vertex)
  }
  return pathLength;
}

Graph Interfaces

public interface BasicGraphInterface<T> {
    boolean addVertex(T vertexLabel);
    boolean addEdge(T begin, T end, double edgeWeight);
    boolean addEdge(T begin, T end);
    boolean hasEdge(T begin, T end);
    boolean isEmpty();
    int getNumberOfVertices();
    int getNumberOfEdges();
    void clear();
}
public interface GraphAlgorithmsInterface<T> {
    QueueInterface<T> getBreadthFirstTraversal(T origin);
    QueueInterface<T> getDepthFirstTraversal(T origin);
    StackInterface<T> getTopologicalOrder();
    int getShortestPath(T begin, T end, StackInterface<T> path);
    double getCheaprestPath(T begin, T end, StackInterface<T> path);
}

Implementation

Two ways to implement graph:

  1. Array: A two-dimensional square array.
  2. List.

Vertices and Edges

What the Vertex class needs:

Vertex interface:

public interface VertexInterface<T> {
    T getLabel();
    void visit();
    void unvisit();
    boolean isVisited();
    boolean connect(VertexInterface<T> endVertex, double edgeWeight);
    boolean connect(VertexInterface<T> endVertex);
    Iterator<VertexInterface<T>> getNeighborIterator();
    Iterator<Double> getWeightIterator();
    boolean hasNeighbor();
    VertexInterface<T> getUnvisitedNeighbor();
    void setPredecessor(VertexInterfac<T> predecessor);
    VertexInterface<T> getPredecessor();
    boolean hasPredecessor();
    void setCost(double newCost);
    double getCost();
}

Edge inner-class:

protected class Edge {
    private VertexInterface<T> vertex; // Vertex at end of edge
    private double weight;
    protected Edge(VertexInterface<T> endVertex, double edgeWeight) {
        vertex = endVertex;
        weight = edgeWeight;
    }
    protected Edge(VertexInterface<T> endVertex) {
        vertex = endVertex;
        weight = 0;
    }
    protected VertexInterface<T> getEndVertex() {
        return vertex;
    }
    protected double getWeight() {
        return weight;
    }
}

Directed graph:

public class DirectedGraph<T> implements GraphInterface<T> {
    private DictionaryInterface<T> VertexInterface<T>> vertices;
    private int edgeCount;
    public DirectedGraph() {
        vertices = new LinkeDictionary<>();
        edgeCount = 0;
    }
}

Important: Remember to check if getCost() returned no path every time you use it.

Digraph: A set of distinct vertices and distinct edges.