본문으로 건너뛰기 Graph Data Structure | Adjacency List· Matrix

Graph Data Structure | Adjacency List· Matrix

Graph Data Structure | Adjacency List· Matrix

이 글의 핵심

Complete guide to graph data structures for coding interviews. Master adjacency list, adjacency matrix, BFS, and DFS with principles and code examples.

Introduction

”Data Structure for Representing Connections”

A graph consists of nodes (vertices) and edges. It’s a more general structure than trees.

1. Graph Basics

Terminology

    1 --- 2
    |     |
    3 --- 4
- Vertex: 1, 2, 3, 4
- Edge: 1-2, 1-3, 2-4, 3-4
- Degree: Number of edges connected to vertex (degree of 1 = 2)
- Path: 1 → 2 → 4
- Cycle: 1 → 2 → 4 → 3 → 1

Graph Types

1) Directed Graph:

1 → 2
↓   ↓
3 → 4

2) Undirected Graph:

1 - 2
|   |
3 - 4

3) Weighted Graph:

    5
1 --- 2
|  3  |
3 --- 4
    2

2. Graph Representation

Adjacency List

Adjacency list stores only directly connected neighbors for each vertex. Like subway stations listing only transfer stations, it’s space-efficient for sparse graphs.

# Undirected graph
graph = {
    1: [2, 3],
    2: [1, 4],
    3: [1, 4],
    4: [2, 3]
}
# Directed graph
graph = {
    1: [2, 3],
    2: [4],
    3: [4],
    4: []
}
# Weighted graph
graph = {
    1: [(2, 5), (3, 3)],  # (node, weight)
    2: [(1, 5), (4, 2)],
    3: [(1, 3), (4, 2)],
    4: [(2, 2), (3, 2)]
}

Adjacency Matrix

Adjacency matrix uses grid cell [i][j] to indicate if edge exists between vertices i and j. Checks edge existence in O(1) but requires O(V²) memory.

# Undirected graph (4 vertices)
graph = [
    [0, 1, 1, 0],  # Vertex 1
    [1, 0, 0, 1],  # Vertex 2
    [1, 0, 0, 1],  # Vertex 3
    [0, 1, 1, 0]   # Vertex 4
]
# Weighted graph
graph = [
    [0, 5, 3, 0],
    [5, 0, 0, 2],
    [3, 0, 0, 2],
    [0, 2, 2, 0]
]
# Check edge
if graph[0][1] > 0:
    print("1-2 connected")

Comparison

FeatureAdjacency ListAdjacency Matrix
SpaceO(V+E)O(V²)
Check edgeO(V)O(1)
Full traversalO(V+E)O(V²)
ImplementationComplexSimple
Best forSparse graphsDense graphs

3. Graph Traversal

from collections import deque
def bfs(graph, start):
    visited = set([start])
    queue = deque([start])
    result = []
    
    while queue:
        node = queue.popleft()
        result.append(node)
        
        for neighbor in graph[node]:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)
    
    return result
# Test
graph = {1: [2, 3], 2: [1, 4], 3: [1, 4], 4: [2, 3]}
print(bfs(graph, 1))  # [1, 2, 3, 4]
def dfs(graph, node, visited, result):
    visited.add(node)
    result.append(node)
    
    for neighbor in graph[node]:
        if neighbor not in visited:
            dfs(graph, neighbor, visited, result)
# Usage
visited = set()
result = []
dfs(graph, 1, visited, result)
print(result)  # [1, 2, 4, 3]

Iterative DFS (using stack):

def dfs_iterative(graph, start):
    visited = set()
    stack = [start]
    result = []
    
    while stack:
        node = stack.pop()
        
        if node not in visited:
            visited.add(node)
            result.append(node)
            
            # Add neighbors in reverse order
            for neighbor in reversed(graph[node]):
                if neighbor not in visited:
                    stack.append(neighbor)
    
    return result

4. Problem Solving

Problem 1: Count Connected Components

def count_components(n, edges):
    """
    Count connected components in undirected graph
    """
    graph = {i: [] for i in range(n)}
    for a, b in edges:
        graph[a].append(b)
        graph[b].append(a)
    
    visited = set()
    count = 0
    
    def dfs(node):
        visited.add(node)
        for neighbor in graph[node]:
            if neighbor not in visited:
                dfs(neighbor)
    
    for i in range(n):
        if i not in visited:
            dfs(i)
            count += 1
    
    return count
# Test
n = 5
edges = [[0, 1], [1, 2], [3, 4]]
print(count_components(n, edges))  # 2

Problem 2: Path Exists

from collections import deque
def has_path(graph, start, end):
    """
    Check if path exists from start to end
    """
    visited = set()
    queue = deque([start])
    visited.add(start)
    
    while queue:
        node = queue.popleft()
        
        if node == end:
            return True
        
        for neighbor in graph[node]:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)
    
    return False
# Test
graph = {1: [2, 3], 2: [4], 3: [], 4: []}
print(has_path(graph, 1, 4))  # True
print(has_path(graph, 1, 5))  # False

Problem 3: Shortest Path (Unweighted)

from collections import deque
def shortest_path(graph, start, end):
    """
    Find shortest path length in unweighted graph
    """
    if start == end:
        return 0
    
    visited = set([start])
    queue = deque([(start, 0)])  # (node, distance)
    
    while queue:
        node, dist = queue.popleft()
        
        for neighbor in graph[node]:
            if neighbor == end:
                return dist + 1
            
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append((neighbor, dist + 1))
    
    return -1  # No path
# Test
graph = {1: [2, 3], 2: [4], 3: [4], 4: []}
print(shortest_path(graph, 1, 4))  # 2 (1→2→4)

Problem 4: Cycle Detection

def has_cycle(graph):
    """
    Detect cycle in directed graph
    """
    visited = set()
    rec_stack = set()  # Recursion stack
    
    def dfs(node):
        visited.add(node)
        rec_stack.add(node)
        
        for neighbor in graph[node]:
            if neighbor not in visited:
                if dfs(neighbor):
                    return True
            elif neighbor in rec_stack:
                return True  # Back edge found
        
        rec_stack.remove(node)
        return False
    
    for node in graph:
        if node not in visited:
            if dfs(node):
                return True
    
    return False
# Test
graph = {1: [2], 2: [3], 3: [1]}  # Cycle: 1→2→3→1
print(has_cycle(graph))  # True

5. Practical Tips

Coding Interview Tips

# ✅ Check input format
# - Edge list → convert to adjacency list
# - 1-indexed vs 0-indexed
# ✅ Watch for directed graphs
# Undirected: graph[a].append(b), graph[b].append(a)
# Directed: graph[a].append(b) only
# ✅ Always track visited
# Prevent cycles and infinite loops
# ✅ Choose representation
# Sparse graph (E << V²): adjacency list
# Dense graph (E ≈ V²): adjacency matrix

BFS vs DFS Selection

Use CaseAlgorithmReason
Shortest pathBFSLevel-order guarantees shortest
All pathsDFSExplores deeply
Connected componentsEitherBoth work
Cycle detectionDFSTrack recursion stack
Topological sortDFSPostorder gives reverse topo

Summary

Key Points

  1. Graph: Vertices and edges, represent connections
  2. Representation: Adjacency list (sparse), adjacency matrix (dense)
  3. Traversal: BFS (shortest path), DFS (all paths)
  4. Time Complexity: O(V+E)

Space Complexity

RepresentationSpaceBest For
Adjacency ListO(V+E)Sparse graphs (social networks)
Adjacency MatrixO(V²)Dense graphs (complete graphs)

Beginner

  • LeetCode 200: Number of Islands
  • LeetCode 733: Flood Fill
  • LeetCode 997: Find the Town Judge

Intermediate

  • LeetCode 133: Clone Graph
  • LeetCode 207: Course Schedule
  • LeetCode 323: Number of Connected Components

Advanced

  • LeetCode 269: Alien Dictionary
  • LeetCode 310: Minimum Height Trees
  • LeetCode 332: Reconstruct Itinerary


Keywords

Graph, Data Structure, Adjacency List, Adjacency Matrix, BFS, DFS, Graph Traversal, Shortest Path, Cycle Detection, Connected Components, Coding Interview, Algorithm


Frequently Asked Questions (FAQ)

Q. When would I use this in practice?

A. Complete guide to graph data structures for coding interviews. Master adjacency list, adjacency matrix, BFS, and DFS wit…

Q. What should I read before this?

A. Follow the previous article or related articles links at the bottom of each post to learn in sequence.

Q. Where can I study this more deeply?

A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.


Other articles related to this topic.


Keywords Covered in This Article (Related Search Terms)

This article covers Algorithm, Data Structure, Graph, BFS, DFS, Coding Interview.