Introduction

A graph is a pictorial representation of a set of objects where some pairs of objects are connected by links. The interconnected objects are represented by points termed as Vertices, and the links that connect the vertices are called Edges. It consists of following two components:

  1. A finite set of vertices also called as nodes.
  2. A finite set of ordered pair of the form (u, v) called as edge.

Pair of form (u, v) indicates that there is an edge from vertex u to vertex v. The edges may contain weight/value/cost.

Representations

Representation of a graph largely depends on the operations we intend to support. A graph can be represented using

  1. Adjacency Matrix
  2. Incidence Matrix
  3. Adjacency List

Adjacency Matrix

Graph is represented using a matrix of size total number of vertices by total number of vertices. So a graph with 4 vertices can be represented using a matrix of 4×4. In this matrix, rows and columns both represents vertices. This matrix is filled with either 1 or 0. 1 represents there is an edge from row vertex to column vertex and 0 represents there is no edge from row vertex to column vertex. An undirected graph the matrix is symmetric and 0 along the diagonal. Directed graphs can have 1s in arbitrary positions, ad its not symmetric along diagonal. 

Let the 2D array be adj[][], adj[i][j] = 1 indicates that there is an edge from vertex i to vertex j. Adjacency Matrix is also used to represent weighted graphs. If adj[i][j] = w, then there is an edge from vertex i to vertex j with weight w.

Adjacency Matrix of Graph
Adjacency Matrix of Graph
// Graph representation using array of ArrayList
public class Graph{
  
  private int v;
  private ArrayList<ArrayList<Integer>> adj;

  // Initialize the Graph with number of vertices
  public Graph(int v) {
    this.v = v;
    adj = new ArrayList<ArrayList<Integer>>();

    for (int i = 0; i < v; i++) {
        adj.add(new ArrayList<Integer>());
    }
  }

  // Add an edge between node u and v
  void addEdge(int u, int v){
     adj.get(u).add(v);
  }
}

Removing an edge takes O(1) time. Queries like whether there is an edge from vertex ‘u’ to vertex ‘v’ are efficient and can be done O(1). Consumes more space O(V^2), even if the graph is sparse(contains less number of edges). Adding a vertex is O(V^2) time.

Incidence Matrix

Graph is represented using a matrix of size total number of vertices by total number of edges. In this matrix, rows represents vertices and columns represents edges. This matrix is filled with either 0 or 1 or -1. Here, 0 represents row edge is not connected to column vertex, 1 represents row edge is connected as outgoing edge to column vertex and -1 represents row edge is connected as incoming edge to column vertex.

Incidence Matrix of Graph
Incidence Matrix of Graph

Adjacency List

An array of linked lists is used. Size of the array is equal to number of vertices. Let the array be array[]. An entry array[i] represents the linked list of vertices adjacent to the ith vertex. This representation can also be used to represent a weighted graph. The weights of edges can be stored in nodes of linked lists. 

// Graph representation using array of LinkedList
public class Graph{
  
  private int v;
  private LinkedList<integer> adj[];

  // Initialize the Graph with number of vertices
  public Graph(int v) {
    this.v = v;
    adj = new LinkedList[v];
    for (int i = 0; i < v; i++) {
        adj[i] = new LinkedList<Integer>();
    }
  }

  // Add an edge between node u and v
  void addEdge(int u, int v){
     adj[u].add(v);
  }
}


// Graph representation using HashMap
// HashMap keys represent the node and the values are the lists of neighbors.		 
Map<Integer, List<Integer>> adjList = new HashMap<Integer, List<Integer>>();
		  
adjList.put(0, Arrays.asList(1));
adjList.put(1, Arrays.asList(0, 2));
adjList.put(2, Arrays.asList(1, 0));
adjList.put(3, Arrays.asList(1, 2));