← Back to Home

Module 1 - Graphs

Module Overview

Learn about graph data structures and their applications in recommendation systems.

Understanding Graphs

A graph data structure is constructed of a set of nodes (also called vertices) connected by edges. Unlike trees, edges don't represent a parent-child relationship between nodes. Instead, they connect nodes to create a neighbor relationship.

Key graph concepts:

Graphs are used in many real-world scenarios like:

Graph Traversal Algorithms

There are two primary methods for traversing (searching) graphs:

Breadth-First Search (BFS)

BFS explores a graph level by level, visiting all immediate neighbors before moving to the next level. It's useful for finding the shortest path between nodes in an unweighted graph.

BFS uses a queue to keep track of nodes to visit:

// Pseudocode for BFS
function BFS(graph, startNode, targetNode) {
  let queue = new Queue();
  let visited = new Set();

  queue.enqueue(startNode);

  while (!queue.isEmpty()) {
    let currentNode = queue.dequeue();

    if (currentNode === targetNode) {
      return true; // Found the target
    }

    if (!visited.has(currentNode)) {
      visited.add(currentNode);

      // Add all unvisited neighbors to queue
      for (let neighbor of graph.getNeighbors(currentNode)) {
        if (!visited.has(neighbor)) {
          queue.enqueue(neighbor);
        }
      }
    }
  }

  return false; // Target not found
}

Depth-First Search (DFS)

DFS explores as far as possible along a branch before backtracking. It's useful for detecting cycles and exploring all possible paths.

DFS uses a stack (or recursion) to track nodes to visit:

// Pseudocode for DFS
function DFS(graph, startNode, targetNode) {
  let stack = new Stack();
  let visited = new Set();

  stack.push(startNode);

  while (!stack.isEmpty()) {
    let currentNode = stack.pop();

    if (currentNode === targetNode) {
      return true; // Found the target
    }

    if (!visited.has(currentNode)) {
      visited.add(currentNode);

      // Add all unvisited neighbors to stack
      for (let neighbor of graph.getNeighbors(currentNode)) {
        if (!visited.has(neighbor)) {
          stack.push(neighbor);
        }
      }
    }
  }

  return false; // Target not found
}

When implementing graphs, there are two common representations:

Learning Objectives

Resources