#1 To Check, if Graph is a Tree? in JAVA

Polkam SrinidhiPolkam Srinidhi
4 min read

1. Graph-Style DSA Problem: Is the Graph a Tree?

Problem Statement: The problem is to determine whether the given undirected graph is a tree.
Conditions to satisfy for sure: A graph is a tree if:

  • It is connected.

  • It does not contain any cycles.

  • It has exactly n - 1 edges for n nodes.

Solution Outline:

  • Use Depth First Search (DFS) or Breadth First Search (BFS) to check if the graph is connected.

  • Detect cycles using DFS or BFS.

  • Check if the number of edges is n - 1.

import java.util.*;

public class GraphTreeCheck{
    public static boolean dfs(int node, int parent, boolean[] visited, List<List<Integer>> graph) {
        visited[node] = true;
        for (int neighbor : graph.get(node)) 
        /*graph.get(node)
        this means adjacent nodes list of current nodes traversal
        eg: graph = [[1,3],[1,3],[2,0]]
        first case: node=0, parent=-1, visited=[],graph
        so for looks like
        neighbor=1(0-index of graph has 1 as o-index in its adjacent list)
        graph.get(0) => [1,3] => helps to traverse across adjlist of current node
        */
        {
            if (!visited[neighbor])
            /*this checks if we visited the neighbour node go check else if
            it means this if traverses to visit neighbour nodes by extending it to recursion dfs
            mainly to traverse all nodes and mark true for visited nodes
            how it gonna help?
            yes, 1. we can check if the graph is connected or not
            bcoz, if any node is there but not visited it means that graph is not connected
            try this example for more details:[[1],[0],[]] 
            here node 2 is not connected to any node in graph, hence this is identified*/
            {
                if (!dfs(neighbor, node, visited, graph)) return false;
            } else if (neighbor != parent)
            /* this else if checks for cycle
            if it is true, i.e neighbor != parent 
            it means we can reach to this neighbour node from some other other it means it is cyclic
            if it false, then
            we can reach neighbhoyr only from the parent node(actual current or the node from which we got the neighbour)
             */
            {
                return false; // cycle detected
            }
        }
        return true;
        /*THis true ensures:
        1. we have travesed every node of graph and store the visit(1) not-visit(0) in visited array
            this helps isTree func to detect if every node is connected(tree) or not-connected(not tree)
        2. in traversing by parent node use we conclude graph is not cycle*/
    }

    public static boolean isTree(int n, int m, List<List<Integer>> graph) {
        if (m != n - 1) return false; // A tree must have exactly n-1 edges

        boolean[] visited = new boolean[n];
        if (!dfs(0, -1, visited, graph))
        return false;
        /* this if says:
        starts the dfs traversal frorm node 0 recursion starts and we will get
        if is true that means dfs is false it mean either we detected cyclic graph
        if is false means graph donot have cycle and 
        now check for connected or not-connected graph through visited arr
        */


        for (boolean v : visited) {
            if (!v) return false; // The graph is not connected
            /*
            if some inex-node value is 0 it means it is not connected into any nodes of graph
            hence not connected graph false
            */
        }
        return true;
        /*true means, all nodes are 1 it means all r connected to one anothe and withput cyclic 
        so yes it is tree hapily returned now
*/
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        List<List<Integer>> graph = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            graph.add(new ArrayList<>());
        }

        for (int i = 0; i < m; i++) {
            int u = scanner.nextInt();
            int v = scanner.nextInt();
            graph.get(u).add(v);
            graph.get(v).add(u);
        }

        if (isTree(n, m, graph)) {
            System.out.println("Tree");
            System.out.println(graph);
        } else {
            System.out.println("Not a Tree");
        }
    }
}
/*input 1:
3
2
0 1
1 2
Output 1:
Tree
[[1], [0, 2], [1]] // this is connected, non-cyclic, m=n-1 graph so tree too

input 2:
3
1
0 1
Output 2:
Not a Tree
[[1], [0], []] // this is not-connected, non-cyclic, m!=n-1 graph so not a tree

input 3:
4
4
0 1
1 2
2 3
3 0
Output 3:
Not a Tree
[[1, 3], [0, 2], [1, 3], [2, 0]] //this is connected, cyclic, m!=n-1 graph so not a tree

*/

The following are input 1, 2, 3 and outputs explained roughly for better uderstanding

0
Subscribe to my newsletter

Read articles from Polkam Srinidhi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Polkam Srinidhi
Polkam Srinidhi

I am a final year student graduates on May 2024, started my journey into practical approach of learning Tech Stacks with open source contribution and Projects.