Notes & software courses · Free to learn
Aph's Blog
On this page

Graph & BFS/DFS

👋 อ่านฟรีทั้งหมดบน Aph's Blog — เนื้อหาภาษาไทย ทำตามทีละหน้าใน sidebar ได้เลย หากมีข้อเสนอแนะหรืออยากให้เพิ่มหัวข้อไหน บอกได้เสมอ

โครงสร้างความสัมพันธ์ (จุด-เส้น) และการท่องด้วย BFS/DFS — แผนที่ โซเชียล เส้นทาง

graph คือโครงสร้างที่มี "จุด" (vertex/node) เชื่อมด้วย "เส้น" (edge) ใช้แทนความสัมพันธ์ได้ทุกอย่าง: เพื่อนในโซเชียล, แผนที่ถนน, การพึ่งพากันของงาน — และเป็นหัวข้อสุดท้ายที่รวมหลายแนวคิดเข้าด้วยกัน

แทน graph ด้วย adjacency list

python
# graph: A-B, A-C, B-D, C-D
graph = {
    "A": ["B", "C"],
    "B": ["A", "D"],
    "C": ["A", "D"],
    "D": ["B", "C"],
}
# directed = เส้นมีทิศ; weighted = เส้นมีน้ำหนัก (ระยะทาง/ค่าใช้จ่าย)

BFS — ค้นแบบกว้าง (ใช้ queue)

เยี่ยมทีละชั้นจากจุดเริ่ม ใช้ queue (deque) — หา "ระยะสั้นสุด" ใน graph ที่เส้นไม่มีน้ำหนักได้

python
from collections import deque

def bfs(graph, start):
    visited = set([start])
    queue = deque([start])
    order = []
    while queue:
        node = queue.popleft()
        order.append(node)
        for neighbor in graph[node]:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)
    return order

print(bfs(graph, "A"))   # ['A', 'B', 'C', 'D']

DFS — ค้นแบบลึก (ใช้ recursion/stack)

python
def dfs(graph, start, visited=None):
    if visited is None:
        visited = set()
    visited.add(start)
    print(start, end=" ")
    for neighbor in graph[start]:
        if neighbor not in visited:
            dfs(graph, neighbor, visited)

dfs(graph, "A")   # A B D C  (ลงลึกก่อน)
BFS vs DFS

BFS ใช้ queue เยี่ยมทีละชั้น เหมาะหา shortest path (unweighted); DFS ใช้ recursion/stack ลงลึกก่อน เหมาะตรวจ connectivity/หาเส้นทาง สังเกตว่า tree (หัวข้อก่อน) คือ graph ชนิดพิเศษ และทั้งคู่ใช้ queue/stack (หัวข้อแรก ๆ) — บทนี้รวมทุกอย่างเข้าด้วยกัน

นับ connected components

python
def count_components(graph):
    visited = set()
    count = 0
    for node in graph:
        if node not in visited:
            count += 1
            # ท่องทุก node ที่เชื่อมถึงด้วย BFS/DFS
            stack = [node]
            while stack:
                n = stack.pop()
                if n not in visited:
                    visited.add(n)
                    stack.extend(graph[n])
    return count

สรุปหัวข้อนี้ & จบบทเด่น

  • graph = จุด (vertex) + เส้น (edge); แทนด้วย adjacency list (dict)
  • BFS: queue, เยี่ยมทีละชั้น → shortest path (unweighted)
  • DFS: recursion/stack, ลงลึกก่อน → connectivity/หาเส้นทาง
  • tree คือ graph พิเศษ; BFS/DFS ใช้ queue/stack ที่เรียนต้นบท
แบบฝึกหัด

1) สร้าง graph แล้วเขียน BFS 2) เขียน DFS (recursion) 3) หาว่า 2 node เชื่อมถึงกันไหม 4) นับจำนวน connected components

เรียนจบบทเด่นแล้ว — ฝึกต่อให้แน่น

DSA ต้องฝึกโจทย์เยอะถึงจะคล่อง ไปต่อที่คอร์สโจทย์ฝึก (Practice Problems) บนเว็บนี้ ที่มีโจทย์แยกตามหัวข้อให้ลองทำ แล้วค่อยไปส่วนเตรียมตัวสายงานใน SE Roadmap