Tutorials Logic, IN info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Website Development
Practice
Quiz Challenge Interview Questions Certification Practice
Tools
Online Compiler JSON Formatter Regex Tester CSS Unit Converter Color Picker
Compiler Tools

Graph Data Structure BFS, DFS, Adjacency List: Tutorial, Examples, FAQs & Interview Tips

What is a Graph?

A graph G = (V, E) consists of a set of vertices (nodes) V and a set of edges E connecting pairs of vertices. Graphs model real-world relationships: social networks, road maps, web links, dependencies, and more.

TypeDescriptionExample
UndirectedEdges have no direction (A-B = B-A)Facebook friendships
Directed (Digraph)Edges have direction (A->B >= B->A)Twitter follows, web links
WeightedEdges have costs/weightsRoad distances, network latency
Cyclic / AcyclicContains / doesn't contain cyclesDAG for task scheduling

Graph Representations

Graph - Adjacency List, BFS, DFS
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_set>
using namespace std;

class Graph {
    int V;
    vector<vector<int>> adj;
public:
    Graph(int v) : V(v), adj(v) {}

    void addEdge(int u, int v) {
        adj[u].push_back(v);
        adj[v].push_back(u);  // undirected
    }

    // BFS - O(V + E)
    vector<int> bfs(int src) {
        vector<bool> visited(V, false);
        vector<int> order;
        queue<int> q;
        visited[src] = true;
        q.push(src);
        while (!q.empty()) {
            int node = q.front(); q.pop();
            order.push_back(node);
            for (int nb : adj[node]) {
                if (!visited[nb]) { visited[nb] = true; q.push(nb); }
            }
        }
        return order;
    }

    // DFS - O(V + E)
    void dfsHelper(int node, vector<bool>& visited, vector<int>& order) {
        visited[node] = true;
        order.push_back(node);
        for (int nb : adj[node])
            if (!visited[nb]) dfsHelper(nb, visited, order);
    }

    vector<int> dfs(int src) {
        vector<bool> visited(V, false);
        vector<int> order;
        dfsHelper(src, visited, order);
        return order;
    }
};

int main() {
    Graph g(6);
    g.addEdge(0,1); g.addEdge(0,2); g.addEdge(1,3);
    g.addEdge(2,4); g.addEdge(3,5);

    auto bfsOrder = g.bfs(0);
    cout << "BFS: ";
    for (int x : bfsOrder) cout << x << " ";
    cout << endl;  // 0 1 2 3 4 5

    auto dfsOrder = g.dfs(0);
    cout << "DFS: ";
    for (int x : dfsOrder) cout << x << " ";
    cout << endl;  // 0 1 3 5 2 4
    return 0;
}
import java.util.*;

public class Graph {
    int V;
    List<List<Integer>> adj;

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

    void addEdge(int u, int v) {
        adj.get(u).add(v);
        adj.get(v).add(u);
    }

    List<Integer> bfs(int src) {
        boolean[] visited = new boolean[V];
        List<Integer> order = new ArrayList<>();
        Queue<Integer> q = new LinkedList<>();
        visited[src] = true; q.offer(src);
        while (!q.isEmpty()) {
            int node = q.poll(); order.add(node);
            for (int nb : adj.get(node))
                if (!visited[nb]) { visited[nb] = true; q.offer(nb); }
        }
        return order;
    }

    void dfsHelper(int node, boolean[] visited, List<Integer> order) {
        visited[node] = true; order.add(node);
        for (int nb : adj.get(node))
            if (!visited[nb]) dfsHelper(nb, visited, order);
    }

    List<Integer> dfs(int src) {
        boolean[] visited = new boolean[V];
        List<Integer> order = new ArrayList<>();
        dfsHelper(src, visited, order);
        return order;
    }

    public static void main(String[] args) {
        Graph g = new Graph(6);
        g.addEdge(0,1); g.addEdge(0,2); g.addEdge(1,3);
        g.addEdge(2,4); g.addEdge(3,5);
        System.out.println("BFS: " + g.bfs(0));  // [0, 1, 2, 3, 4, 5]
        System.out.println("DFS: " + g.dfs(0));  // [0, 1, 3, 5, 2, 4]
    }
}
from collections import defaultdict, deque

class Graph:
    def __init__(self):
        self.adj = defaultdict(list)

    def add_edge(self, u, v):
        self.adj[u].append(v)
        self.adj[v].append(u)  # undirected

    def bfs(self, src):
        visited = {src}
        queue = deque([src])
        order = []
        while queue:
            node = queue.popleft()
            order.append(node)
            for nb in self.adj[node]:
                if nb not in visited:
                    visited.add(nb)
                    queue.append(nb)
        return order

    def dfs(self, src, visited=None, order=None):
        if visited is None: visited = set()
        if order is None: order = []
        visited.add(src)
        order.append(src)
        for nb in self.adj[src]:
            if nb not in visited:
                self.dfs(nb, visited, order)
        return order

    def has_cycle(self):
        """Detect cycle in undirected graph using DFS"""
        visited = set()
        def dfs_cycle(node, parent):
            visited.add(node)
            for nb in self.adj[node]:
                if nb not in visited:
                    if dfs_cycle(nb, node): return True
                elif nb != parent:
                    return True  # back edge = cycle
            return False
        for node in self.adj:
            if node not in visited:
                if dfs_cycle(node, -1): return True
        return False

g = Graph()
for u, v in [(0,1),(0,2),(1,3),(2,4),(3,5)]:
    g.add_edge(u, v)

print("BFS:", g.bfs(0))  # [0, 1, 2, 3, 4, 5]
print("DFS:", g.dfs(0))  # [0, 1, 3, 5, 2, 4]
print("Has cycle:", g.has_cycle())  # False
class Graph {
    constructor() { this.adj = new Map(); }

    addEdge(u, v) {
        if (!this.adj.has(u)) this.adj.set(u, []);
        if (!this.adj.has(v)) this.adj.set(v, []);
        this.adj.get(u).push(v);
        this.adj.get(v).push(u);
    }

    bfs(src) {
        const visited = new Set([src]);
        const queue = [src], order = [];
        while (queue.length) {
            const node = queue.shift();
            order.push(node);
            for (const nb of (this.adj.get(node) || [])) {
                if (!visited.has(nb)) { visited.add(nb); queue.push(nb); }
            }
        }
        return order;
    }

    dfs(src, visited = new Set(), order = []) {
        visited.add(src);
        order.push(src);
        for (const nb of (this.adj.get(src) || [])) {
            if (!visited.has(nb)) this.dfs(nb, visited, order);
        }
        return order;
    }

    // Shortest path (unweighted) using BFS
    shortestPath(src, dest) {
        const dist = new Map([[src, 0]]);
        const queue = [src];
        while (queue.length) {
            const node = queue.shift();
            if (node === dest) return dist.get(dest);
            for (const nb of (this.adj.get(node) || [])) {
                if (!dist.has(nb)) {
                    dist.set(nb, dist.get(node) + 1);
                    queue.push(nb);
                }
            }
        }
        return -1;  // not reachable
    }
}

const g = new Graph();
[[0,1],[0,2],[1,3],[2,4],[3,5]].forEach(([u,v]) => g.addEdge(u,v));
console.log("BFS:", g.bfs(0));  // [0, 1, 2, 3, 4, 5]
console.log("DFS:", g.dfs(0));  // [0, 1, 3, 5, 2, 4]
console.log("Shortest 0->5:", g.shortestPath(0, 5));  // 3

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.