Showing posts with label graphs. Show all posts
Showing posts with label graphs. Show all posts

Friday, October 31, 2025

Detect Cycle in an Undirected Graph Using BFS - Java Program

In the post Detect Cycle in an Undirected Graph Using DFS - Java Program we saw how to detect a cycle in an undirected graph using DFS, in this tutorial we'll see how to write a Java program to detect a cycle in an undirected graph using breadth-first search traversal.

For example, in the following graph 0-2-3-4-0 is a cycle.

Undirected Graph Cycle

Refer post Java Program - Breadth First Search (BFS) Traversal For Graph to know in details about breadt-first search traversal of a graph.

Detecting a cycle in an undirected graph

Logic for detecting a graph with graph traversal is simple. If the vertex currently visited has already been visited that means there is a cycle in the graph.

With undirected graph, you also have to consider the fact that the connection between vertices is considered bi-directional. Edge between A and B also means an edge between B and A. This bi-directional connection should not be considered a cycle. For this reason, you also need to keep track of the parent vertex of the current vertex. When list of the adjacent vertices for the current vertex is iterated, connection back to the parent vertex should be ignored.

Cycle detection in an undirected graph using BFS - Java Program

In the Java program adjacency list is used to represent the graph. There is a visited array to keep track of the vertices which are already visited.

Program also displays the vertices which are part of the cycle, a HashMap is used to store the vertices that are part of the cycle.

BFS traversal and the cycle detection logic is in the bfs() method which uses a queue to store the adjacent vertices. You also need to keep track of the parent therefore queue adds the vertex and its parent vertex both as an array.

Queue<int[]> queue = new LinkedList<>();

While traversing the graph using breadth-first search, if you come across a vertex that is already visited but not the parent of the current vertex that means there is a cycle.

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

public class UndirectedGraphCycleBFS {
  private Map<Integer, List<Integer>> adjList;
  private int numOfVertices;

  UndirectedGraphCycleBFS(int numOfVertices){
    this.numOfVertices = numOfVertices;
    adjList = new HashMap<>();
  }
  
  // Creating adjacency list 
  public void addEdge(Integer source, Integer destination) {
    adjList.computeIfAbsent(source, k->new ArrayList<>()).add(destination);
    // For undirected graph
    adjList.computeIfAbsent(destination, k->new ArrayList<>()).add(source);
  }
  
  public void printGraph() {
    adjList.forEach((k, v) -> {
      System.out.print("Vertex " + k + " Connectes to ");
      v.forEach(e -> System.out.print(e + " "));
      System.out.println();
    });
  }
  
  /*Cycle detection logic starts here */
  public boolean isCycleDetected() {
    boolean[] visited = new boolean[numOfVertices];
    for(int i = 0; i < numOfVertices; i++) {
      if(!visited[i]) {
        if(bfs(i, visited)) {
          return true;
        }
      }
    }
    return false;
  }
  
  private boolean bfs(int currentVertex, boolean[] visited) {
    // Queue needs to add parent info for the current vertex
    Queue<int[]> queue = new LinkedList<>();
    // For starting vertex parent is -1
    queue.add(new int[]{currentVertex, -1});
    visited[currentVertex] = true;
    // This map is used to keep track of the vertices that are part of the cycle
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    map.put(currentVertex, -1);

    while(!queue.isEmpty()) {
      int[] v = queue.poll();
      int node = v[0];
      int parent = v[1];          
      for(int n : adjList.get(node)) {
              
        if(!visited[n]) {
          visited[n] = true;
          queue.add(new int[]{n, node});
          map.put(n, node);
        }else if(n != parent) { // cycle detected
          // display vertices that are part of the cycle
          printCycle(map, node, n);
          return true;
        }
      }               
    }
    return false;
  }
  
  // Helper method to print the cycle vertices
  private void printCycle(Map<Integer, Integer> parentMap, int u, int v) {
    List<Integer> cycle = new ArrayList<>();
    // Start from the node that caused the cycle detection
    cycle.add(v); 

    int current = u;
    while (current != -1 && current != v) {
      cycle.add(current);
      current = parentMap.get(current);
    }
    Collections.reverse(cycle); // Reverse to get the cycle in order
    cycle.add(parentMap.get(v)); // Add the last vertex
   
    System.out.println("Cycle vertices: " + cycle);
  }
  
  public static void main(String[] args) {
    UndirectedGraphCycleBFS graph = new UndirectedGraphCycleBFS(10);
        
    
//  graph.addEdge(0, 1);
//  graph.addEdge(0, 2);
//  graph.addEdge(0, 3);
//  graph.addEdge(0, 7); 
//  graph.addEdge(1, 4);
//  graph.addEdge(4, 5);
//  graph.addEdge(2, 5);
//  graph.addEdge(3, 6);// Creates a cycle 0-1-4-5-2-0

    
    graph.addEdge(0, 1); 
    graph.addEdge(0, 2); 
    graph.addEdge(0, 4); 
    graph.addEdge(2, 3);
    graph.addEdge(3, 4);// Creates a cycle [0, 2, 3, 4, 0]
        
    graph.printGraph(); 
    
    if(graph.isCycleDetected()) {
      System.out.println("Cycle found in the graph");
    }else {
      System.out.println("No cycle found in the graph");
    }

  }

}

Output

Vertex 0 Connectes to 1 2 4 
Vertex 1 Connectes to 0 
Vertex 2 Connectes to 0 3 
Vertex 3 Connectes to 2 4 
Vertex 4 Connectes to 0 3 
Cycle vertices: [0, 4, 3, 2]
Cycle found in the graph

Time and space complexity of cycle detection in an undirected graph using BFS

With adjacency list only adjacent vertices are stored as a list for each vertex. For each vertex, the DFS algorithm iterates over adjacency list of that vertex. In an adjacency list representation, every edge appears exactly once (directed graph) or twice (undirected graph).

Since the total time = time for vertex processing + time for scanning adjacency list for each vertex = O(V) + O(E) So, the time complexity is O(V + E).

Extra space is needed for visited array which is O(V). In recursive method, call stack may go up to the recursive depth of V in worst case so recursive call space requirement is O(V). Thus, the space complexity can be considered as O(V).

Note that storing adjacency list is also O(V + E) in case you want to include input graph too in the space complexity.

That's all for this topic Detect Cycle in an Undirected Graph Using BFS - Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Weighted Graph Adjacency Representation - Java Program
  2. Java Program to Add and Remove in Graph
  3. Java Program - Depth First Search (DFS) Traversal For Graph
  4. Find Minimum and Maximum Value Nodes in Binary Search Tree - Java Program
  5. Java Program to Create Your Own BlockingQueue

You may also like-

  1. Manacher's Algorithm to Find The Longest Palindrome - Java Program
  2. Reading Delimited File in Java Using Scanner
  3. How to Create PDF From XML Using Apache FOP
  4. Find The Maximum Element in Each Row of a Matrix Java Program
  5. Just In Time Compiler (JIT) in Java
  6. Spring MVC File Download Example
  7. Passing Query Parameters in Angular Routing
  8. Named Tuple in Python

Thursday, October 30, 2025

Detect Cycle in an Undirected Graph Using DFS - Java Program

In this post we'll see how to detect a cycle in an undirected graph using depth-first search traversal.

For example, in the following graph 0-2-3-4-0 is a cycle.

Undirected Graph Cycle

Refer post Java Program - Depth First Search (DFS) Traversal For Graph to know in details about DFS traversal of a graph.

Detecting a cycle in an undirected graph

Logic for detecting a graph with graph traversal is simple. If the vertex currently visited has already been visited that means there is a cycle in the graph.

With undirected graph, you also have to consider the fact that the connection between vertices is considered bi-directional. Edge between A and B also means an edge between B and A. This bi-directional connection should not be considered a cycle. For this reason, you also need to keep track of the parent vertex of the current vertex. When list of the adjacent vertices for the current vertex is iterated, connection back to the parent vertex should be ignored.

Cycle detection in an undirected graph - Java Program

In the Java program, adjacency list is used to represent the graph. There is a visited array to keep track of the vertices which are already visited.

Refer post Graph Adjacency Representation - Java Program to get better explanation of graph adjacency representation using adjacency matrix or adjacency list.

Program also displays the vertices which are part of the cycle, stack is used to store those vertices.

DFS traversal and the cycle detection logic is in the dfs() method which is called recursively with the adjacent vertex of the current vertex to keep going deep in the current branch. You also keep track of the parent and make a check to ignore such bi-directional connection.

if(v == parent) {			
  continue;
}

Here is the complete Java program

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
 * Undirected graph cycle detection using DFS
 */
public class UndirectedGraphCycle {
  private Map<Integer, List<Integer>> adjList;
  private int numOfVertices;
  private Stack<Integer> stack;
  UndirectedGraphCycle(int numOfVertices){
    this.numOfVertices = numOfVertices;
    adjList = new HashMap<>();
    // to keep track of the vertex for the cycle, stack is used
    // so that vertices which are visited and not part of the cycle
    // can be easily popped
    stack = new Stack<>();
  }
  
  public void addEdge(Integer source, Integer destination) {
    adjList.computeIfAbsent(source, k->new ArrayList<>()).add(destination);
    // For undirected graph
    adjList.computeIfAbsent(destination, k->new ArrayList<>()).add(source);
  }
  
  public void printGraph() {
    adjList.forEach((k, v) -> {
      System.out.print("Vertex " + k + " Connectes to ");
      v.forEach(e -> System.out.print(e + " "));
      System.out.println();
    });
  }
  
  public boolean isCycleDetected() {
    boolean[] visited = new boolean[numOfVertices];
    for(int i = 0; i < numOfVertices; i++) {
      if(!visited[i]) {
        if(dfs(i, visited, -1)) {
          return true;
        }
      }
    }
    return false;
  }
  
  // Uses DFS traversal (recursive) to detect a cycle
  private boolean dfs(int currentVertex, boolean[] visited, int parent) {
    visited[currentVertex] = true;
    stack.push(currentVertex);

    for(int v : adjList.get(currentVertex)) {
      System.out.println("Vertex " + v + " Currentv " + currentVertex);
      // undirected graph means 2 way connection so 
      // connection back to parent doesn't mean cycle
      if(v == parent) {
        
        continue;
      }
      // visited array at index is true means that vertex is already visited
      // means a cycle
      if(visited[v]) {
        /*Start - To display the vertices which are part of the cycle */
        List<Integer> cycle = new ArrayList<>();
        int startIndex = stack.indexOf(v);
        for (int i = startIndex; i < stack.size(); i++) {
          cycle.add(stack.get(i));
        }
        // Add the starting node to complete the cycle
        cycle.add(v); 
        System.out.println("Detected cycle is " + cycle);
        /*Display logic ends here comment from start to end 
         * if cycle display not needed*/
        return true;
      }
      // recursive call
      if(dfs(v, visited, currentVertex))
        return true;
    }
    // reached here means current vertex is not part of the cycle so pop it
    stack.pop();
    return false;
  }
  
  public static void main(String[] args) {
    UndirectedGraphCycle graph = new UndirectedGraphCycle(5);

    graph.addEdge(0, 1); //A-B
    //graph.addEdge(1, 2); //A-C
    graph.addEdge(0, 2); //A-C
    graph.addEdge(0, 4); //A-E
    graph.addEdge(2, 3); //C-D
    graph.addEdge(3, 4); //D-E
    
    graph.printGraph(); 
    if(graph.isCycleDetected()) {
      System.out.println("Cycle detected in the graph");
    }else {
      System.out.println("No Cycle detected in the graph");
    }
  }
}

Output

Vertex 0 Connectes to 1 2 4 
Vertex 1 Connectes to 0 
Vertex 2 Connectes to 0 3 
Vertex 3 Connectes to 2 4 
Vertex 4 Connectes to 0 3 
Detected cycle is [0, 2, 3, 4, 0]
Cycle detected in the graph

Time and space complexity of cycle detection in an undirected graph

With adjacency list only adjacent vertices are stored as a list for each vertex. For each vertex, the DFS algorithm iterates over adjacency list of that vertex. In an adjacency list representation, every edge appears exactly once (directed graph) or twice (undirected graph).

Since the total time = time for vertex processing + time for scanning adjacency list for each vertex = O(V) + O(E) So, the time complexity is O(V + E).

Extra space is needed for visited array which is O(V). In recursive method, call stack may go up to the recursive depth of V in worst case so recursive call space requirement is O(V). Thus, the space complexity can be considered as O(V).

Note that space for storing adjacency list is O(V + E), in case you want to include input graph too in the space complexity.

That's all for this topic Detect Cycle in an Undirected Graph Using DFS - Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Weighted Graph Adjacency Representation - Java Program
  2. Java Program to Add and Remove in Graph
  3. Java Program - Breadth First Search (BFS) Traversal For Graph
  4. Java Program to Delete a Node From Binary Search Tree (BST)
  5. How to Remove Elements From an Array Java Program

You may also like-

  1. Rabin-Karp Algorithm For Pattern Search - Java Program
  2. How to Sort Elements in Different Order in Java TreeSet
  3. Find Largest and Second Largest Number in Given Array Java Program
  4. How to Display Time in AM-PM Format in Java
  5. CopyOnWriteArrayList in Java With Examples
  6. Spring Boot Microservice Circuit Breaker Using Resilience4j
  7. NgNonBindable Directive in Angular
  8. Accessing Characters in Python String

Wednesday, October 29, 2025

Java Program - Breadth First Search (BFS) Traversal For Graph

In this post we'll see how to write a Java program for breadth-first search (BFS) traversal of a graph.

Graph traversal

To traverse a graph, where you try to reach all the connected vertices from the starting vertex, can be done in following ways-

  1. Depth-first search (DFS)
  2. Breadth-first search (BFS)

Breadth-first search

Contrary to DFS traversal, where algorithm works by moving away from the starting point and trying to go deep, BFS traversal works by visiting all adjacent vertices from the start vertex. Once all the adjacent vertices are exhausted then only it goes to the next level so it tries to traverse the whole breadth of the level before moving to the next level.

For example, if we have the following graph and the starting vertex is "A".

Depth First Search (DFS) Traversal of graph

From "A" you have to go to any unvisited vertex, adjacent to "A". Let's say in this case it goes to "B" then you need to visit the next adjacent vertex of current vertex "A", which will be "C" same way "D" and "E". With this order ABCDE the current level is exhausted (you have explored the full breadth of this branch) so you need to go to the next level.

You have to pick the next current vertex from the current level of "BCDE", if it is "B" then the next adjacent vertex from current vertex "B" is "F". Since there is no other adjacent vertex from "B" so you need to pick another vertex from the "BCDE" level. If it is "C" then the next adjacent vertex from current vertex "C" is "G".

That's the way you do the BFS traversal of the given graph getting the order as "ABCDEFGHIJ".

Breadth-First Search Java program

For implementing Breath-First Search graph traversal program in Java, queue data structure is used to store the vertices that are already visited. Graph may have cycles so you need to keep track of visited vertices by having an extra array of all vertices and you mark the vertices which are already visited.

Graph can be represented using adjacency matrix or by using adjacency list, which of these two ways is used to represent the graph has to be taken in account while writing Java program for BFS traversal of the graph.

Note that in this article undirected graph traversal is done.

Refer post Graph Adjacency Representation - Java Program to get better explanation of graph adjacency representation using adjacency matrix or adjacency list.

Process for Breadth-First Search traversal is as given below-

  1. From the current vertex, visit an adjacent vertex which is not yet visited, mark it as visited and add it to the queue.
  2. Keep repeating step 1 while there are still unvisited adjacent vertices from the current vertex. If there is no unvisited adjacent vertex left then remove a vertex from queue and make it the current vertex. Again, start step 1.
  3. Process is done when queue is empty.

Here is the complete BFS traversal Java program when adjacency matrix is used to represent graph.

import java.util.LinkedList;
import java.util.Queue;

public class GraphBFSAM{
  private int numOfVertices;
  private int[][] adjMatrix;
  // to store all the vertex labels
  Vertex[] vertices;
  private int temp = 0;
  
  // Vertex class as nested class
  static class Vertex{
    String label;
    // to track the visited vertices
    boolean visited;
    Vertex(String label){
      this.label = label;
    }
    public String getLabel() {
      return label;
    }
    public void setLabel(String label) {
      this.label = label;
    }
    public boolean isVisited() {
      return visited;
    }
    public void setVisited(boolean visited) {
      this.visited = visited;
    }    
  }
  
  GraphBFSAM(int numOfVertices){
    this.numOfVertices = numOfVertices;
    vertices = new Vertex[numOfVertices];
    adjMatrix = new int[numOfVertices][numOfVertices];
  }
  
  //Method to add all the graph vertices
  public void addVertex(String label) {
    vertices[temp++] = new Vertex(label);
  }
  
  public void addEdge(int source, int destination) {
    if((source < 0 || source > numOfVertices) || (destination < 0 || destination > numOfVertices)) {
      System.out.println("Invalid edge addition");
      return;
    }
    adjMatrix[source][destination] = 1;
    // For undirected graph reverse setting also required
    adjMatrix[destination][source] = 1;
  }
  
  public void printGraph() {
    for(int i = 0; i < adjMatrix.length; i++) {
      for(int j = 0; j < adjMatrix[0].length; j++) {
        System.out.print(adjMatrix[i][j] + "\t");
      }
      System.out.println();
    }
  }
  
  public void bfsTraversal(int startVertex) {
    Queue<Integer> queue = new LinkedList<Integer>();
    queue.add(startVertex);
    vertices[startVertex].setVisited(true);
    while(!queue.isEmpty()) {
      int currentVertex = queue.poll();
      System.out.print(vertices[currentVertex].getLabel() + " ");
          //Keep adding to the queue while there are still adjacent vertices
      for(int i = 0; i < adjMatrix.length; i++) {
        if(adjMatrix[currentVertex][i] == 1 && !vertices[i].isVisited()) {
          queue.add(i);
          vertices[i].setVisited(true);
        }
      }      
    }
  }
  
  public static void main(String[] args) {
    GraphBFSAM graph = new GraphBFSAM(10);
    graph.addVertex("A");
    graph.addVertex("B");
    graph.addVertex("C");
    graph.addVertex("D");
    graph.addVertex("E");
    graph.addVertex("F");
    graph.addVertex("G");
    graph.addVertex("H");
    graph.addVertex("I");
    graph.addVertex("J");
    
    graph.addEdge(0, 1); //A-B
    graph.addEdge(0, 2); //A-C
    graph.addEdge(0, 3); //A-D
    graph.addEdge(0, 4); //A-E
    graph.addEdge(1, 5); //B-F
    graph.addEdge(5, 8); //F-I
    graph.addEdge(2, 6); //C-G
    graph.addEdge(4, 7); //E-H
    graph.addEdge(7, 9); //H-J


    //graph.printGraph();
    graph.bfsTraversal(0);

  }
}

Output

A B C D E F G H I J

Important points about the program

  1. Uses a static inner class Vertex to encapsulate a vertex with fields as label to store the label of the vertex and Boolean field visited to keep track of the vertex which is already visited.
  2. Adjacency matrix is used here to represent a graph.
  3. Array named vertices is used to store the vertices of the graph and mark the vertices which are already visited.

Here is the complete Java program when adjacency list is used to represent the graph.

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;

public class GraphBFSAL {
  private Map<String, List<String>> adjList;
  // To keep track of already visited vertices
  private Set<String> visited;
  
  GraphBFSAL(){
    adjList = new HashMap<>();
    visited = new HashSet<String>();
  }
  
  public void addVertex(String v) {
    adjList.putIfAbsent(v, new ArrayList<String>());
  }
  
  public void addEdge(String source, String destination) {

    if(!adjList.containsKey(source)) {
      addVertex(source);
    }
    if(!adjList.containsKey(destination)) {
      addVertex(destination);
    }
    adjList.get(source).add(destination);
    // Reverse link also required for undirected graph
    //adjList.get(destination).add(source);
  }
  
  // Method to display graph
  public void printGraph() {
    adjList.forEach((k, v) -> {
      System.out.print("Vertex " + k+ " connects to ");
      v.forEach(e -> System.out.print(e + " "));
      System.out.println();
    });
  }
  
  public void bfsTraversal(String startVertex) {
    Queue<String> queue = new LinkedList<String>();
    queue.add(startVertex);
    visited.add(startVertex);
    while(!queue.isEmpty()) {
      String currentVertex = queue.poll();
      System.out.print(currentVertex+ " ");
      for (String s : adjList.getOrDefault(currentVertex, Collections.emptyList())) {
              if (!visited.contains(s)) {
                queue.add(s);
                visited.add(s);
              }
          }
    }
  }
  
  public static void main(String[] args) {
    GraphBFSAL graph = new GraphBFSAL();

    graph.addEdge("A", "B");
    graph.addEdge("A", "C");
    graph.addEdge("A", "D");
    graph.addEdge("A", "E");
    graph.addEdge("B", "F");
    graph.addEdge("F", "I");
    graph.addEdge("C", "G");
    graph.addEdge("E", "H");
    graph.addEdge("H", "J");
    
    //graph.printGraph();
    graph.bfsTraversal("A");
  }

}

Output

A B C D E F G H I J

Important points about the program-

  1. In the Java program Map and List collections are used to represent adjacency list.
  2. A HashSet named visited is used to store the vertices of the graph and mark the vertices which are already visited.

Time and space complexity of BFS graph traversal

If total number of vertices in the graph are V and the total number of edges are E then the time complexity is O(V2) when graph is represented as an adjacency matrix.

In adjacency matrix we have a 2D array of VXV which means while checking for neighbours of any vertex we have to scan the whole row which is O(V) time, meaning O(V2) for V vertices.

With adjacency list only adjacent vertices are stored as a list for each vertex. For each vertex, the algorithm iterates over adjacency list of that vertex. In an adjacency list representation, every edge appears exactly once (directed graph) or twice (undirected graph). Since the total time = time for vertex processing + time for scanning adjacency list for each vertex = O(V) + O(E)

So, the time complexity is O(V + E).

Auxiliary space requirement is O(V) to store visited vertices in an array or set. Queue may also end up storing V vertices (in worst case) so the space requirement is O(V) for the Queue used in the method.

Thus, the total space requirement is O(V) + O(V), discarding the constants the space complexity is O(V).

Note that adjacency list also takes O(V + E) space and adjacency matrix O(V2) space.

That's all for this topic Java Program - Breadth First Search (BFS) Traversal For Graph. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Weighted Graph Adjacency Representation - Java Program
  2. Java Program to Add and Remove in Graph
  3. Binary Tree Traversal Using Breadth First Search Java Program
  4. Linked List Implementation Java Program
  5. Ternary Search Program in Java

You may also like-

  1. Java Program to Get All DB Schemas
  2. Comparing Enum to String in Java
  3. Arrange Non-Negative Integers to Form Largest Number - Java Program
  4. Printing Numbers in Sequence Using Threads Java Program
  5. Association, Aggregation And Composition in Java
  6. Java Map getOrDefault() Method With Examples
  7. Lazy Initialization in Spring Using lazy-init And @Lazy Annotation
  8. Pure and Impure Pipes in Angular

Thursday, October 23, 2025

Java Program - Depth First Search (DFS) Traversal For Graph

In this post we'll see how to write a Java program for depth-first search (DFS) traversal of a graph.

Graph traversal

To traverse a graph, where you try to reach all the connected vertices from the starting vertex, can be done in following ways-

  1. Depth-first search (DFS)
  2. Breadth-first search (BFS)

Depth-First Search

DFS traversal tries to traverse all adjacent vertices from the start vertex, it tries to go deep while exploring a branch and backtracks to starting point once it reaches dead end to start exploring another branch.

For example, if we have the following graph and the starting vertex is "A".

Depth First Search (DFS) Traversal of graph

From "A" you have to go to any vertex, adjacent to "A". So, you see there can be multiple DFS traversal orders of a graph based on how adjacent vertex is picked. Let's say in this case it goes to "B" then you need to visit the next adjacent vertex, which will be "F" and then "I". With this order ABFI the current branch reaches a dead end (you have explored the full depth of this branch) so you need to backtrack and then pick the next adjacent vertex from starting point "A" which is "C" and so on. Final DFS traversal order is A B F I C G D E H J.

DFS traversal for graph is similar to Binary tree DFS traversal with one difference, graph may have cycles so you need to keep track of visited vertices by having an extra array of all vertices and you mark the vertices which are already visited.

Depth-First Search Java program

Depth-First Search traversal program can be written using a recursive method or by using an iterative method with a stack to keep track of traversal.

Graph can be represented using adjacency matrix or by using adjacency list, which of these two ways is used to represent the graph has to be taken in account while writing Java program for DFS traversal of the graph. Note that in this article undirected graph traversal is done.

Refer post Graph Adjacency Representation - Java Program to get better explanation of graph adjacency representation using adjacency matrix or adjacency list.

Process for DFS traversal is as given below-

For recursive logic

  1. Start from the starting vertex and mark it as visited.
  2. Recursively visit all the unvisited adjacent vertices. Mark the visited vertices.
  3. Backtrack when no unvisited adjacent vertices left.

For iterative logic

  1. Start from the starting vertex, mark it as visited and push it on the stack
  2. Visit an unvisited adjacent vertex. Mark the vertex as visited and push it on the stack
  3. Keep doing step 2 while there are adjacent vertices in that branch.
  4. When there are no unvisited adjacent vertices, backtrack by popping vertex of the stack and look for adjacent vertex in another branch.

Here is the complete Java program with both recursive and iterative methods when adjacency matrix is used to represent graph.

import java.util.Stack;

public class GraphBFS {
  private int numOfVertices;
  private int[][] adjMatrix;
  // to store all the vertex labels
  Vertex[] vertices;
  private int temp = 0;
  
  // Vertex class as nested class
  static class Vertex{
    String label;
    // to track the visited vertices
    boolean visited;
    Vertex(String label){
      this.label = label;
    }
    public String getLabel() {
      return label;
    }
    public void setLabel(String label) {
      this.label = label;
    }
    public boolean isVisited() {
      return visited;
    }
    public void setVisited(boolean visited) {
      this.visited = visited;
    }    
  }
  
  GraphBFS(int numOfVertices){
    this.numOfVertices = numOfVertices;
    vertices = new GraphBFS.Vertex[numOfVertices];
    adjMatrix = new int[numOfVertices][numOfVertices];
  }
  
  //Method to add all the graph vertices
  public void addVertex(String label) {
    vertices[temp++] = new Vertex(label);
  }
  
  public void addEdge(int source, int destination) {
    if((source < 0 || source > numOfVertices) || (destination < 0 || destination > numOfVertices)) {
      System.out.println("Invalid edge addition");
      return;
    }
    adjMatrix[source][destination] = 1;
    // For undirected graph reverse setting also required
    adjMatrix[destination][source] = 1;
  }
  
  public void printGraph() {
    for(int i = 0; i < adjMatrix.length; i++) {
      for(int j = 0; j < adjMatrix[0].length; j++) {
        System.out.print(adjMatrix[i][j] + "\t");
      }
      System.out.println();
    }
  }
  
  /* Recursive logic start */
  public void dfs(int startVertex) {
    
    System.out.println("DFS Traversal (Recursive): ");
    dfsRecursive(startVertex, vertices);
  }
  
  public void dfsRecursive(int startVertex, Vertex[] vertices) {
    vertices[startVertex].setVisited(true);
    System.out.print(vertices[startVertex].getLabel() + " ");
    for (int i = 0; i < numOfVertices; i++) {
      if (adjMatrix[startVertex][i] == 1 && !vertices[i].isVisited()) {
        dfsRecursive(i, vertices);
      }
    }
  }
  /* Recursive logic End */
  /* Iterative logic Start */
  public void dfsIterative(int startVertex) {
    boolean[] visited = new boolean[numOfVertices];
    Stack<Integer> stack = new Stack<Integer>();
    stack.push(startVertex);
    
    visited[startVertex] = true;
    
    System.out.print(vertices[startVertex].getLabel() + " ");
    while(!stack.isEmpty()) {
      int v = getNextUnvisitedVertex(stack.peek(), visited);
      if(v == -1) {
        stack.pop();
      }else {
        visited[v] = true;
        System.out.print(vertices[v].getLabel() + " ");
        //System.out.println(v);
        stack.push(v);
      }
    }
  }
  
  private int getNextUnvisitedVertex(int v, boolean[] visited) {
    for(int i = 0; i < numOfVertices; i++) {
      if(adjMatrix[v][i] == 1 && visited[i] == false) {
        return i;
      }
    }
    return -1;
  }
  /* Iterative logic End */
  
  public static void main(String[] args) {
    GraphBFS graph = new GraphBFS(10);
    graph.addVertex("A");
    graph.addVertex("B");
    graph.addVertex("C");
    graph.addVertex("D");
    graph.addVertex("E");
    graph.addVertex("F");
    graph.addVertex("G");
    graph.addVertex("H");
    graph.addVertex("I");
    graph.addVertex("J");
    
    graph.addEdge(0, 1); //A-B
    graph.addEdge(0, 2); //A-C
    graph.addEdge(0, 3); //A-D
    graph.addEdge(0, 4); //A-E
    graph.addEdge(1, 5); //B-F
    graph.addEdge(5, 8); //F-I
    graph.addEdge(2, 6); //C-G
    graph.addEdge(4, 7); //E-H
    graph.addEdge(7, 9); //H-J

    //graph.printGraph();
    graph.dfs(0);
    System.out.println("");
    System.out.println("Graph DFS Traversal (Iterative): ");
    graph.dfsIterative(0);

  }
}

Output

DFS Traversal (Recursive): 
A B F I C G D E H J 
Graph DFS Traversal (Iterative): 
A B F I C G D E H J 

Important points about the program

  1. Uses a static inner class Vertex to encapsulate a vertex with fields as label to store the label of the vertex and Boolean field visited to keep track of the vertex which is already visited.
  2. Adjacency matrix is used here to represent a graph.
  3. Array named vertices is used to store the vertices of the graph and mark the vertices which are already visited.
  4. Method named dfsRecursive() shows the recursive logic.
  5. Method named dfsIterative () shows the iterative logic.

Here is the complete Java program with both recursive and iterative methods when adjacency list is used to represent graph.

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

public class GrapdhDFSAL {

  private Map<String, List<String>> adjList;
  // To keep track of already visited vertices
  private Set<String> visited;
  
  GrapdhDFSAL(){
    adjList = new HashMap<>();
    visited = new HashSet<String>();
  }
  
  public void addVertex(String v) {
    adjList.putIfAbsent(v, new ArrayList<String>());
  }
  
  public void addEdge(String source, String destination) {

    if(!adjList.containsKey(source)) {
      addVertex(source);
    }
    if(!adjList.containsKey(destination)) {
      addVertex(destination);
    }
    adjList.get(source).add(destination);
    // Reverse link also required for undirected graph
    adjList.get(destination).add(source);
  }
  
  // Method to display graph
  public void printGraph() {
    adjList.forEach((k, v) -> {
      System.out.print("Vertex " + k+ " connects to ");
      v.forEach(e -> System.out.print(e + " "));
      System.out.println();
    });
  }
  
  /* Recursive logic start */
  public void dfs(String startVertex) {
    System.out.println("DFS Traversal (Recursive): ");
    dfsRecursive(startVertex);
  }
  
  public void dfsRecursive(String startVertex) {
    visited.add(startVertex);
    
    System.out.print(startVertex + " ");
    for (String s : adjList.getOrDefault(startVertex, Collections.emptyList())) {
      if (!visited.contains(s)) {
        dfsRecursive(s);
      }
    }
  }
  /* Recursive logic end */
  
  /* Iterative logic Start */
  public void dfsIterative(String startVertex) {
    Stack<String> stack = new Stack<String>();
    stack.push(startVertex);
    
    visited.add(startVertex);
    
    System.out.print(startVertex + " ");
    while(!stack.isEmpty()) {
      String v = getNextUnvisitedVertex(stack.peek());
      if(v.isBlank()) {
        stack.pop();
      }else {
        visited.add(v);
        System.out.print(v + " ");
        stack.push(v);
      }
    }
  }
  
  private String getNextUnvisitedVertex(String v) {
    for (String s : adjList.getOrDefault(v, Collections.emptyList())) {
      if (!visited.contains(s)) {
        return s;
      }
    }
    return "";
  }
  /* Iterative logic End */
  public static void main(String[] args) {
    GrapdhDFSAL graph = new GrapdhDFSAL();

    graph.addEdge("A", "B");
    graph.addEdge("A", "C");
    graph.addEdge("A", "D");
    graph.addEdge("A", "E");
    graph.addEdge("B", "F");
    graph.addEdge("F", "I");
    graph.addEdge("C", "G");
    graph.addEdge("E", "H");
    graph.addEdge("H", "J");
    graph.printGraph();
    // Uncomment this to run recursive method
    //System.out.println("Graph DFS Traversal (Recursive): ");
    //graph.dfs("A");
    System.out.println("Graph DFS Traversal (Iterative): ");
    graph.dfsIterative("A");

  }
}

Output

Vertex A connects to B C D E 
Vertex B connects to A F 
Vertex C connects to A G 
Vertex D connects to A 
Vertex E connects to A H 
Vertex F connects to B I 
Vertex G connects to C 
Vertex H connects to E J 
Vertex I connects to F 
Vertex J connects to H 
Graph DFS Traversal (Iterative): 
A B F I C G D E H J 

Important points about the program

  1. In the Java program, Map and List collections are used to represent adjacency list.
  2. A HashSet named visited is used to store the vertices of the graph and mark the vertices which are already visited.
  3. Method named dfsRecursive() shows the recursive logic.
  4. Method named dfsIterative () shows the iterative logic.

Time and space complexity of DFS graph traversal

If total number of vertices in the graph are V and the total number of edges are E then the time complexity is O(V2) when graph is represented as an adjacency matrix.

In adjacency matrix we have a 2D array of VXV which means while checking for neighbours of any vertex we have to scan the whole row which is O(V) meaning O(V2) for V vertices.

With adjacency list, only adjacent vertices are stored as a list for each vertex. For each vertex, the algorithm iterates over adjacency list of that vertex. In an adjacency list representation, every edge appears exactly once (directed graph) or twice (undirected graph).

Since the total time = time for vertex processing + time for scanning adjacency list for each vertex = O(V) + O(E) So, the time complexity is O(V + E).

Auxiliary space requirement is O(V) to store visited vertices in an array or set. In recursive method, call stack may go up to the recursive depth of V in worst case so recursive call space requirement is O(V).

For iterative method, stack may also end up storing V vertices (in worst case) so the space requirement is O(V) for stack used in iterative method. Thus, the total space requirement is O(V) + O(V), discarding the constants the space complexity is O(V).

That's all for this topic Java Program - Depth First Search (DFS) Traversal For Graph. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Weighted Graph Adjacency Representation - Java Program
  2. Java Program to Add and Remove in Graph
  3. Binary Tree Traversal Using Breadth First Search Java Program
  4. Linked List Implementation Java Program
  5. Bucket Sort Program in Java

You may also like-

  1. Compress And Decompress File Using GZIP Format in Java
  2. Convert Numbers to Words Java Program
  3. Java Program - Sieve of Eratosthenes to Find Prime Numbers
  4. Convert HTML to PDF in Java + Openhtmltopdf and PDFBox
  5. How to Sort ArrayList of Custom Objects in Java
  6. Primitive Data Types in Java
  7. Spring JdbcTemplate Insert, Update And Delete Example
  8. Angular Access Control CanActivate Route Guard Example

Thursday, October 16, 2025

Java Program to Add and Remove in Graph

In this post we'll see how to write Java program for addition and removal from a graph data structure.

Addition and removal in a graph can be done in the following scenarios-

  1. Adding a vertex
  2. Adding an edge
  3. Removing a vertex
  4. Removing an edge

Another thing to consider while writing Java program for graph addition, removal is the representation of graph-

  1. Graph is represented using adjacency matrix
  2. Graph is represented using adjacency list

Please refer following posts to know more about graph representations- Graph Adjacency Representation - Java Program
Weighted Graph Adjacency Representation - Java Program

Graph addition removal Java program - Adjacency list representation

In the program, Map storing lists of its neighbours is used as adjacency list representation.

A separate class called Vertex is also there to encapsulate vertex information.

Adding a vertex means, adding that vertex as a key in the Map, along with a new ArrayList as a value.

Adding an edge means adding both the start vertex and the end vertex and the reverse link too if it is an undirected graph.

Removing a vertex means removing that particular key from the Map. Also remove where ever the removed vertex is listed as neighbour for other vertices.

Removing an edge means removing the link from starting point to end point, reverse link for the same vertices should also be removed for an undirected graph.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Insert, delete in graph represented as adjacency list
 */
public class GraphDSAL {
  Map<Vertex, List<Vertex>> adjList = new HashMap<>();
  // Vertex class as nested class
  static class Vertex{
    String label;
    Vertex(String label){
      this.label = label;
    }
    public String getLabel() {
      return label;
    }
    public void setLabel(String label) {
      this.label = label;
    }
    @Override
    public int hashCode() {
      return Objects.hash(label);
    }
    @Override
    public boolean equals(Object obj) {
      if (this == obj)
        return true;
      if (obj == null)
        return false;
      if (getClass() != obj.getClass())
        return false;
      Vertex other = (Vertex) obj;
      return Objects.equals(label, other.label);
    }
    
  }
  
  public void addVertex(Vertex v) {
    adjList.putIfAbsent(v, new ArrayList<Vertex>());
  }
  
  public void removeVertex(Vertex v) {
    // remove vertex
    adjList.remove(v);
    // remove where ever the removed vertex is listed as neighbour
    adjList.values().forEach(e -> e.remove(v));
  }
  
  public void addEdge(String source, String destination) {
    Vertex vs = new Vertex(source);
      Vertex vd = new Vertex(destination);
    if(!adjList.containsKey(vs)) {
      addVertex(vs);
    }
    if(!adjList.containsKey(vd)) {
      addVertex(vd);
    }
    adjList.get(vs).add(vd);
    // Reverse link also required for undirected graph
    adjList.get(vd).add(vs);
  }
  
  public void removeEdge(String source, String destination) {
    Vertex vs = new Vertex(source);
      Vertex vd = new Vertex(destination);
      adjList.get(vs).remove(vd);
      // Reverse link removal also required for undirected graph
      adjList.get(vd).remove(vs);
  }
  // Method to display graph
  public void printGraph() {
    adjList.forEach((k, v) -> {
      System.out.print("Vertex " + k.getLabel() + " connects to ");
      v.forEach(e -> System.out.print(e.getLabel() + " "));
      System.out.println();
    });
  }

  public static void main(String[] args) {
    GraphDSAL graph = new GraphDSAL();
    graph.addVertex(new Vertex("A"));
    graph.addEdge("A", "B");
    graph.addEdge("A", "C");
    graph.addEdge("A", "E");
    graph.addEdge("C", "D");
    graph.addEdge("D", "E");
    
    graph.printGraph();
    
    graph.removeVertex(new Vertex("A"));
    //graph.removeEdge("A", "C");
    System.out.println("After removal");
    graph.printGraph();
        
  }

}

Output

Vertex A connects to B C E 
Vertex B connects to A 
Vertex C connects to A D 
Vertex D connects to C E 
Vertex E connects to A D 
After removal
Vertex B connects to 
Vertex C connects to D 
Vertex D connects to C E 
Vertex E connects to D 

Graph addition removal Java program - Adjacency matrix representation

When graph is represented as an adjacency matrix, that means using a 2-D array to represent a graph.

Adding a vertex means, incrementing the rows and columns of the adjacency matrix by 1 to accommodate new vertex. Copy the rows and columns from the old adjacency matrix to this new one and then assign the new adjacency matrix as the adjacency matrix of the graph.

Adding an edge means changing the row, column value to 1 for the array element, mapping to the start and end vertices for the added edge.

Removing a vertex means, decrementing the rows and columns of the adjacency matrix to represent removal of a vertex. While copying the rows and columns from the old adjacency matrix to this new one ensure that the values for the row and column represented by the removed vertex are not added to the new adjacency matrix. Assign the new adjacency matrix as the adjacency matrix of the graph.

Removing an edge means changing the row, column value to 0 for the array element, mapping to the start and end vertices for the removed edge.

/**
 * Insert, delete in graph represented as adjacency matrix
 */
public class GraphDSAM {
  private int vertices;
  private int[][] adjMatrix;
  
  GraphDSAM(int vertices){
    this.vertices = vertices;
    adjMatrix = new int[vertices][vertices];
  }
  
  public void addEdge(int source, int destination) {
    if((source < 0 || source >= vertices) || (destination < 0 || destination >= vertices)) {
      System.out.println("Invalid edge addition");
      return;
    }
    adjMatrix[source][destination] = 1;
    // For undirected graph reverse setting also required
    adjMatrix[destination][source] = 1;
  }
  
  public void removeEdge(int source, int destination) {
    if((source < 0 || source >= vertices) || (destination < 0 || destination >= vertices)) {
      System.out.println("Invalid edge removal");
      return;
    }
    adjMatrix[source][destination] = 0;
    // For undirected graph reverse setting also required
    adjMatrix[destination][source] = 0;
  }
  
  public void addVertex() {
    int changedSize = vertices + 1;
    int[][] changedAdjMatrix = new int[changedSize][changedSize];

    // Copy existing connections
    for (int i = 0; i < vertices; i++) {
      for (int j = 0; j < vertices; j++) {
        changedAdjMatrix[i][j] = adjMatrix[i][j];
      }
    }
    this.adjMatrix = changedAdjMatrix;
    vertices = changedSize;
  }
  
  public void removeVertex(int v) {
    if(v < 0 || v >= vertices){
      System.out.println("Invalid vertex removal");
      return;
    }
    int[][] changedAdjMatrix = new int[vertices-1][vertices-1];
    // maintaining row for changedAdjMatrix
    int tempRow = 0;
    
    for(int i = 0; i < adjMatrix.length; i++) {
      if(i == v) {
        continue;
      }
      // maintaining col for changedAdjMatrix
      int tempCol = 0;
      for(int j = 0; j < adjMatrix[0].length; j++) {
        if(j == v) {
          continue;
        }
        changedAdjMatrix[tempRow][tempCol] = adjMatrix[i][j];
        tempCol++;
      }
      tempRow++;
      
    }
    this.adjMatrix = changedAdjMatrix;
  }
  
  public void printGraph() {
    for(int i = 0; i < adjMatrix.length; i++) {
      for(int j = 0; j < adjMatrix[0].length; j++) {
        System.out.print(adjMatrix[i][j] + "\t");
      }
      System.out.println();
    }
  }
  
  public static void main(String[] args) {
    GraphDSAM graph = new GraphDSAM(5);
    graph.addEdge(0, 1);
    graph.addEdge(0, 2); 
    graph.addEdge(0, 4); 
    graph.addEdge(2, 3); 
    graph.addEdge(3, 4); 

    graph.printGraph();
    
    System.out.println("After adding a vertex");
    graph.addVertex();
    graph.addEdge(3, 5); 
    graph.printGraph();
    System.out.println("After removal");
    graph.removeEdge(3, 4);
    graph.printGraph();

  }

}

Output

0	1	1	0	1	
1	0	0	0	0	
1	0	0	1	0	
0	0	1	0	1	
1	0	0	1	0	
After adding a vertex
0	1	1	0	1	0	
1	0	0	0	0	0	
1	0	0	1	0	0	
0	0	1	0	1	1	
1	0	0	1	0	0	
0	0	0	1	0	0	
After removal
0	1	1	0	1	0	
1	0	0	0	0	0	
1	0	0	1	0	0	
0	0	1	0	0	1	
1	0	0	0	0	0	
0	0	0	1	0	0	

That's all for this topic Java Program to Add and Remove in Graph. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Binary Tree Traversal Using Breadth First Search Java Program
  2. Binary Tree Traversal Using Depth First Search Java Program
  3. Binary Tree Implementation in Java - Insertion, Traversal And Search
  4. Sorted Linked List In Java
  5. Deque Implementation in Java Using Doubly Linked List

You may also like-

  1. Rabin-Karp Algorithm For Pattern Search - Java Program
  2. Two Sum - Elements in Array With Given Sum Java Program
  3. Java Program - Sieve of Sundaram to Find Prime Numbers
  4. How to Create Password Protected Zip File in Java
  5. Java CyclicBarrier With Examples
  6. static Reference to The Non-static Method or Field Error
  7. Difference Between @Controller And @RestController Annotations in Spring
  8. How to Create a Custom Structural Directive in Angular

Monday, October 13, 2025

Weighted Graph Adjacency Representation - Java Program

In the article Graph Adjacency Representation - Java Program, we saw how to represent an unweighted graph using adjacency list or adjacency matrix. In this post we'll see what is a weighted graph and how to represent a weighted graph using adjacency list or adjacency matrix in Java.

Weighted graph

In a weighted graph, numerical values called weights are assigned to edges. These weights may represent distance, cost, time etc. For example, if vertices in a graph represent cities, then weight of the edges may mean the distances between the cities, cost t travel between cities or time it takes to drive between cities.

Weighted Graph

Weighted graph representation using adjacency matrix

An adjacency matrix is a 2-D array in which weight of the edge is used as elements to indicate whether an edge is present between two vertices or not. For example, adjMat[i][j] stores the weight of the edge between i and j vertices.

If the edge is not present it is represented by value as infinity or zero for that cell in the matrix.

For the above image which represents an undirected weighted graph the adjacency matrix can be visualized as shown below. An undirected graph means that the edges don't have direction and you can traverse both ways. You can go from vertex A to vertex B or from vertex B to vertex A.

Weighted Undirected Graph Adjacency Matrix

Weighted Undirected Graph adjacency matrix Java Program

public class WtGraphAdjMatrix {
  private int vertices;
  private int[][] adjMatrix;

  WtGraphAdjMatrix(int vertices){
    this.vertices = vertices;
    adjMatrix = new int[vertices][vertices];
  }
  
  public void addEdge(int source, int destination, int weight) {
    if((source < 0 || source > vertices) || (destination < 0 || destination > vertices)) {
      System.out.println("Invalid edge addition");
      return;
    }
    adjMatrix[source][destination] = weight;
    // For undirected graph reverse setting also required
    adjMatrix[destination][source] = weight;
  }
  
  public void printGraph() {
    for(int i = 0; i < adjMatrix.length; i++) {
      for(int j = 0; j < adjMatrix[0].length; j++) {
        System.out.print(adjMatrix[i][j] + "\t");
      }
      System.out.println();
    }
  }
  public static void main(String[] args) {
    WtGraphAdjMatrix graph = new WtGraphAdjMatrix(5);
    graph.addEdge(0, 1, 5); //A-B
    graph.addEdge(0, 2, 10); //A-C
    graph.addEdge(0, 4, 7); //A-E
    graph.addEdge(2, 3, 15); //C-D
    graph.addEdge(3, 4, 8); //D-E


    graph.printGraph();
  }
}

Output

0   5	  10	0	  7	
5	  0	  0	  0	  0	
10  0	  0	  15  0	
0	  0	  15	0	  8	
7	  0	  0	  8	  0

Weighted Directed Graph adjacency matrix Java Program

In a directed graph you can traverse in only one direction. The allowed direction is shown with an arrow at the end of the edge.

Weighted Directed Graph

Adjacency matrix for the above weighted directed graph can be visualized as-

Weighted Directed Graph Adjacency Matrix

Java code for the directed Graph adjacency matrix requires just commenting a single line in the above code for the undirected graph, the reverse link in the matrix.

public void addEdge(int source, int destination, int weight) {
  if((source < 0 || source > vertices) || (destination < 0 || destination > vertices)) {
    System.out.println("Invalid edge addition");
    return;
  }
  adjMatrix[source][destination] = weight;
  // For undirected graph reverse setting also required
  //adjMatrix[destination][source] = weight;
}

If you run the code after commenting the line, output is-

0   5	  10	0	  7	
0	  0	  0	  0	  0	
0	  0	  0	  15	0	
0	  0	  0	  0	  8	
0	  0	  0	  0	  0

Weighted Graph representation using adjacency list

Another way to represent a weighted graph is using an adjacency list which is an array of lists or a list of lists. Each vertex has an associated list storing all the adjacent vertices. In this associated list each element will have two values connected vertex and the weight between two vertices.

Adjacency list for the above weighted undirected graph can be visualized as-

Weighted Undirected Graph adjacency list Java Program

In the Java program Map and List collections are used to represent adjacency list. Each map key has an associated list to show the adjacent vertices. There is also a class named Edge that encapsulates the adjacent vertex and weight fields.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WtGraphAdjList {
  int vertices;
  Map<String, List<Edge>> adjList;
  static class Edge{
    String destination;
    int weight;
    Edge(String destination, int weight){
      this.destination = destination;
      this.weight = weight;
    }
  }
  
  WtGraphAdjList(int vertices){
    this.vertices = vertices;
    adjList = new HashMap<>();
  }
  void addEdge(String source, String destination, int weight) {

    adjList.computeIfAbsent(source, k->new ArrayList<>()).add(new Edge(destination, weight));
    // For undirected graph
    adjList.computeIfAbsent(destination, k->new ArrayList<>()).add(new Edge(source, weight));
  }
  
  public void printGraph() {
    for(Map.Entry<String, List<Edge>> es : adjList.entrySet()) {
      System.out.print("Vertex " + es.getKey() + " connects to: ");
      List<Edge> list = es.getValue();
      for (Edge e : list) {
        System.out.print("[" + e.destination + " with weight " + e.weight + "] ");
      }
      System.out.println();
    }
  }
  public static void main(String[] args) {
    WtGraphAdjList graph = new WtGraphAdjList(5);
    graph.addEdge("A", "B", 5);
    graph.addEdge("A", "C", 10);
    graph.addEdge("A", "E", 7);
    graph.addEdge("C", "D", 15);
    graph.addEdge("D", "E", 8);
    
    graph.printGraph();
  }
}

Output

Vertex A connects to: [B with weight 5] [C with weight 10] [E with weight 7] 
Vertex B connects to: [A with weight 5] 
Vertex C connects to: [A with weight 10] [D with weight 15] 
Vertex D connects to: [C with weight 15] [E with weight 8] 
Vertex E connects to: [A with weight 7] [D with weight 8] 

Weighted Directed Graph adjacency list Java Program

In case of directed graph, you can traverse in only one direction.

Java code for the directed Graph adjacency matrix requires just commenting the line that creates a reverse link in the list.

void addEdge(String source, String destination, int weight) {
  adjList.computeIfAbsent(source, k->new ArrayList<>()).add(new Edge(destination, weight));
  // For undirected graph
  //adjList.computeIfAbsent(destination, k->new ArrayList<>()).add(new Edge(source, weight));
}

With that change the output is-

Vertex A connects to: [B with weight 5] [C with weight 10] [E with weight 7] 
Vertex C connects to: [D with weight 15] 
Vertex D connects to: [E with weight 8] 

That's all for this topic Weighted Graph Adjacency Representation - Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Java Program - Depth First Search (DFS) Traversal For Graph
  2. Java Program - Breadth First Search (BFS) Traversal For Graph
  3. Binary Tree Traversal Using Depth First Search Java Program
  4. Java Program to Detect And Remove Loop in a Linked List
  5. Z Algorithm For Pattern Search - Java Program

You may also like-

  1. Deque Implementation in Java Using Doubly Linked List
  2. Arrange Non-Negative Integers to Form Largest Number - Java Program
  3. Radix Sort Program in Java
  4. Display Time in 24 Hours Format in Java
  5. Java Stream - sorted() With Examples
  6. Difference Between Abstract Class And Interface in Java
  7. Lazy Initialization in Spring Using lazy-init And @Lazy Annotation
  8. Angular Two-Way Data Binding With Examples

Friday, October 10, 2025

Graph Adjacency Representation - Java Program

In this post we'll see how to represent a graph using adjacency list and adjacency matrix. Here we'll see representation for the unweighted graph.

Graph is a data structure which is similar to tree and has nodes and edges. Nodes are generally called vertices when it comes to graph.

If you want to see how to represent a weighted graph using adjacency list and adjacency matrix, check this post- Weighted Graph Adjacency Representation - Java Program

What is adjacency

The vertices in a graph are said to be adjacent to one another if they are connected directly by a single edge.

Undirected Graph

The above graph has 5 vertices (A, B, C, D, E) and 5 edges. The circles represent the vertices and the lines connecting them are edges. In the above figure vertex A is adjacent to B and C but A is not adjacent to vertex D.

A binary tree has a fixed structure; each node has a maximum of two children. Graph doesn't have that kind of fixed structure, in a graph each vertex may be connected to an arbitrary number of other vertices. In the above vertex A is connected to B, C and E vertices.

Because of this kind of structure, to represent a graph two methods are generally used-

  1. Adjacency matrix
  2. Adjacency List

Graph representation using adjacency matrix

An adjacency matrix is a 2-D array in which 0 and 1 are used as elements to indicate whether an edge is present between two vertices or not.

  • An edge between two vertices is marked using 1
  • If there is no edge between two vertices then 0 is used

If a graph has n vertices, then adjacency matrix also has n rows and n columns (n X n array).

For the above image which represents an undirected graph the adjacency matrix can be visualized as shown below. An undirected graph means that the edges don't have direction and you can traverse both ways. You can go from vertex A to vertex B or from vertex B to vertex A.

Undirected Graph Adjacency Matrix

Adjacency matrix representation is easy to implement and efficient in terms of accessing any element, but it is less space efficient because you are storing information about all possible edges rather than just actual connections (adjacency list stores only actual connections).

Undirected Graph adjacency matrix Java Program

public class GraphAdjMatrix {
  private int vertices;
  private int[][] adjMatrix;

  GraphAdjMatrix(int vertices){
    this.vertices = vertices;
    // matrix having same row and columns as vertices
    adjMatrix = new int[vertices][vertices];
  }
  
  public void addEdge(int source, int destination) {
    if((source < 0 || source > vertices) || (destination < 0 || destination > vertices)) {
      System.out.println("Invalid edge addition");
      return;
    }
    adjMatrix[source][destination] = 1;
    // For undirected graph reverse setting also required
    adjMatrix[destination][source] = 1;
  }
  
  public void printGraph() {
    for(int i = 0; i < adjMatrix.length; i++) {
      for(int j = 0; j < adjMatrix[0].length; j++) {
        System.out.print(adjMatrix[i][j] + "\t");
      }
      System.out.println();
    }
  }
  
  public static void main(String[] args) {
    GraphAdjMatrix graph = new GraphAdjMatrix(5);
    graph.addEdge(0, 1); //A-B
    graph.addEdge(0, 2); //A-C
    graph.addEdge(0, 4); //A-E
    graph.addEdge(2, 3); //C-D
    graph.addEdge(3, 4); //D-E

    graph.printGraph();

  }
}

Output

0	1	1	0	1	
1	0	0	0	0	
1	0	0	1	0	
0	0	1	0	1	
1	0	0	1	0

Directed Graph adjacency matrix Java Program

In a directed graph you can traverse in only one direction. The allowed direction is shown with an arrow at the end of the edge.

Directed Graph

Adjacency matrix for the above directed graph can be visualized as-

Directed Graph Adjacency Matrix

Java code for the directed Graph adjacency matrix requires just commenting a single line in the above code for the undirected graph, the reverse link in the matrix.

public void addEdge(int source, int destination) {
  if((source < 0 || source > vertices) || (destination < 0 || destination > vertices)) {
    System.out.println("Invalid edge addition");
    return;
  }
  adjMatrix[source][destination] = 1;
  // For undirected graph reverse setting also required
  //adjMatrix[destination][source] = 1;
}

With that the output is-

0	1	1	0	1	
0	0	0	0	0	
0	0	0	1	0	
0	0	0	0	1	
0	0	0	0	0

Graph representation using adjacency list

Another way to represent a graph is using an adjacency list which is an array of lists or a list of lists. Each vertex in a list shows all the adjacent vertices as another list, linked to this vertex.

Adjacency list for the above undirected graph can be visualized as-

Undirected Graph Adjacency List

Undirected Graph adjacency list Java Program

In the Java program Map and List collections are used to represent adjacency list. Each map key has an associated list to show the adjacent vertices.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class GraphAdjList {
  int vertices;
  Map<String, List<String>> adjList;
  
  GraphAdjList(int vertices){
    this.vertices = vertices;
    adjList = new HashMap<>();

  }
  
  public void addEdge(String source, String destination) {
    adjList.computeIfAbsent(source, k->new ArrayList<>()).add(destination);
    // For undirected graph
    adjList.computeIfAbsent(destination, k->new ArrayList<>()).add(source);
  }
  
  public void printGraph() {
    for(Map.Entry<String, List<String>> es :adjList.entrySet()) {
      System.out.print("Vertex " + es.getKey() + " connects to: ");
      List<String> list = es.getValue();
      for (String s : list) {
        System.out.print("[" + s + "] ");
      }
      System.out.println();
    }
  }
  public static void main(String[] args) {
    GraphAdjList graph = new GraphAdjList(5);
    graph.addEdge("A", "B");
    graph.addEdge("A", "C");
    graph.addEdge("A", "E");
    graph.addEdge("C", "D");
    graph.addEdge("D", "E");
    
    graph.printGraph();
  }
}

Output

Vertex A connects to: [B] [C] [E] 
Vertex B connects to: [A] 
Vertex C connects to: [A] [D] 
Vertex D connects to: [C] [E] 
Vertex E connects to: [A] [D] 

As you can see with adjacency list you store only the actual connections so it is more space efficient.

Directed Graph adjacency list Java Program

In case of directed graph, you can traverse in only one direction.

Adjacency list for the above directed graph can be visualized as-

Directed Graph Adjacency List

Java code for the directed Graph adjacency matrix requires just commenting the line that creates a reverse link in the list.

public void addEdge(String source, String destination) {
  adjList.computeIfAbsent(source, k->new ArrayList<>()).add(destination);
  // For undirected graph
  //adjList.computeIfAbsent(destination, k->new ArrayList<>()).add(source);
}

With that change the output is-

Vertex A connects to: [B] [C] [E] 
Vertex C connects to: [D] 
Vertex D connects to: [E] 

That's all for this topic Graph Adjacency Representation - Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Java Program to Add and Remove in Graph
  2. Detect Cycle in an Undirected Graph Using DFS - Java Program
  3. Java Program - Breadth First Search (BFS) Traversal For Graph
  4. Binary Tree Implementation in Java - Insertion, Traversal And Search
  5. Z Algorithm For Pattern Search - Java Program

You may also like-

  1. Heap Sort Program in Java
  2. Interpolation Search Program in Java
  3. Matrix Multiplication Java Program
  4. Longest Prefix Suffix Java Program
  5. Service in Angular With Examples
  6. How to Resolve Local Variable Defined in an Enclosing Scope Must be Final or Effectively Final Error
  7. static Method Overloading or Overriding in Java
  8. List in Python With Examples