Graphs - potatoscript/dsa GitHub Wiki

🌐 Graphs – Web of Connections 🌐

Graphs are one of the most powerful and versatile data structures in computer science. They help us represent a web of connections between different elements. Just like how cities are connected by roads, or how people are connected through social networks, graphs allow us to model real-world relationships in a way that makes it easy to find solutions to complex problems.

In this tutorial, we'll explore graphs in a simple, fun, and easy-to-understand way, so even primary school students can grasp the concept. We'll use visual examples, real-life analogies, and step-by-step explanations to make sure you get a strong foundation in working with graphs!


🧩 What is a Graph?

A graph is a collection of nodes (or vertices) connected by edges (or arcs).

  • Nodes (Vertices): Represent the entities or objects in the graph.
  • Edges (Arcs): Represent the connections or relationships between the nodes.

πŸ“ Real-World Example: Social Network

Imagine you're on a social media platform, and you want to see how friends are connected to each other.

  • Nodes (Vertices): People on the social network (like you, your friends, and your friend’s friends).
  • Edges (Arcs): Friend connections between people.

You can think of a graph as a big network where each node is a person, and each edge is a friendship between two people.


🧩 Types of Graphs

Graphs come in many different types, depending on how edges are represented and how nodes are connected. Here are the two main types of graphs you’ll encounter:

  1. Undirected Graphs:

    • In these graphs, the edges have no direction. The connection between two nodes is mutual (if A is connected to B, B is also connected to A).
    • Example: Social network connections – if two people are friends, they both know each other.
  2. Directed Graphs (Digraphs):

    • In these graphs, the edges have a direction. That means if A is connected to B, it doesn't necessarily mean that B is connected to A.
    • Example: Twitter followers – if A follows B, it doesn’t mean B follows A.

🧩 Components of a Graph

To help visualize and understand graphs, here’s a breakdown of their key components:

  1. Vertex (Node): A point that represents an entity (like a person, city, or website).
  2. Edge (Arc): A line connecting two vertices. It represents a relationship or connection.
  3. Adjacent Vertices: Two vertices that are connected by an edge.
  4. Degree of a Vertex: The number of edges connected to a vertex. In directed graphs, we have in-degree (number of edges coming into the node) and out-degree (number of edges going out of the node).

🧩 Visualizing Graphs

Let’s look at an example of both an undirected graph and a directed graph:

Example 1: Undirected Graph

       A
      / \
     B   C
    /     \
   D       E
  • Vertices: A, B, C, D, E
  • Edges: A-B, A-C, B-D, C-E (undirected edges, meaning if A is connected to B, B is connected to A).

Example 2: Directed Graph

       A β†’ B
       ↑    ↓
       C ← D
  • Vertices: A, B, C, D
  • Edges: Aβ†’B, Aβ†’C, Bβ†’D, Dβ†’C (directed edges, meaning the direction matters).

🧩 Graph Terminology

Here are some important terms related to graphs:

  • Path: A sequence of vertices connected by edges.
  • Cycle: A path that starts and ends at the same vertex.
  • Connected Graph: A graph where there is a path between every pair of vertices.
  • Disconnected Graph: A graph where at least one pair of vertices cannot be reached from each other.
  • Weighted Graph: A graph where each edge has a value (weight). This is useful for representing costs, distances, or times (e.g., roads between cities with distances).

🧩 Types of Graph Traversal

To work with graphs, we often need to traverse them, which means visiting all the nodes and edges in a particular order. There are two main ways to traverse graphs:

1. Depth-First Search (DFS)

DFS starts at a node and explores as far as possible along each branch before backtracking. Imagine you're exploring a maze, and you always go down a path until you can’t go further, then you retrace your steps and try a different path.

  • Steps:
    1. Start at the root node.
    2. Visit a node.
    3. Recursively visit all unvisited adjacent nodes.

DFS Example:

Graph:
     A
    / \
   B   C
  / \   \
 D   E   F

DFS Traversal: A β†’ B β†’ D β†’ E β†’ C β†’ F

2. Breadth-First Search (BFS)

BFS starts at a node and explores all the neighboring nodes at the present depth level before moving on to nodes at the next depth level. Imagine you’re exploring a maze, but instead of going down one path completely, you explore all possible paths at the current level first before going deeper.

  • Steps:
    1. Start at the root node.
    2. Visit all the neighboring nodes.
    3. Move to the next level and repeat.

BFS Example:

Graph:
     A
    / \
   B   C
  / \   \
 D   E   F

BFS Traversal: A β†’ B β†’ C β†’ D β†’ E β†’ F

🧩 C# Code Examples

Graph Node Class (for undirected graph)

public class GraphNode
{
    public string Name;
    public List<GraphNode> Neighbors;

    public GraphNode(string name)
    {
        Name = name;
        Neighbors = new List<GraphNode>();
    }

    // Add an edge between two nodes
    public void AddEdge(GraphNode node)
    {
        Neighbors.Add(node);
    }
}

Depth-First Search (DFS)

public void DFS(GraphNode node)
{
    if (node == null)
        return;

    // Visit the node
    Console.Write(node.Name + " ");
    
    // Visit all unvisited neighbors
    foreach (var neighbor in node.Neighbors)
    {
        DFS(neighbor);
    }
}

Breadth-First Search (BFS)

public void BFS(GraphNode startNode)
{
    Queue<GraphNode> queue = new Queue<GraphNode>();
    HashSet<GraphNode> visited = new HashSet<GraphNode>();

    queue.Enqueue(startNode);
    visited.Add(startNode);

    while (queue.Count > 0)
    {
        var currentNode = queue.Dequeue();
        Console.Write(currentNode.Name + " ");

        // Visit all neighbors of the current node
        foreach (var neighbor in currentNode.Neighbors)
        {
            if (!visited.Contains(neighbor))
            {
                queue.Enqueue(neighbor);
                visited.Add(neighbor);
            }
        }
    }
}

🧩 Applications of Graphs

Graphs are everywhere! Here are a few examples of how graphs are used in real life:

  1. Social Networks: Represent users (nodes) and their connections (edges).
  2. Web Pages: Web pages are connected by hyperlinks, forming a directed graph.
  3. GPS Navigation: Cities and roads can be represented as a graph where edges are roads and nodes are intersections or cities.
  4. Recommendation Systems: Products, users, and their relationships (purchases, reviews) form a graph to suggest new items.

🧩 Time Complexity

  • DFS and BFS: Both DFS and BFS have a time complexity of O(V + E), where V is the number of vertices (nodes) and E is the number of edges in the graph.

⚠️ **GitHub.com Fallback** ⚠️