BFS

youngwiki
Pinkgo (토론 | 기여)님의 2025년 10월 5일 (일) 21:21 판 (개요)

상위 문서: 알고리즘 설계와 분석

개요

BFS(Breadth-First Traversal) 알고리즘의 핵심은 그래프를 체계적으로(순서 있게) 탐색하는 것이다. BFS는 모든 vertex와 edge를 한 번씩 방문한다. 이는 아래와 같은 규칙을 따른다.

  • “Breadth-First”는 탐색 시 가까운 노드(이웃)를 먼저 방문하고, 그 후에 더 멀리 있는 노드를 탐색하는 방식이다.
    • 예를 들어, 루트 노드로부터 거리 1인 정점들을 모두 방문한 뒤, 그 다음으로 거리가 2인 정점, 3인 정점...을 방문하는 방식이다.
  • BFS는 queue(큐)를 이용해 이 순서를 보장한다.

이에 따라 BFS는 특히 unweighted 그래프에서 최단 경로(shortest path)를 찾는 데 적합하다. 이는 DFS(깊이 우선 탐색)와 달리, BFS는 각 vertex까지의 최단 거리(간선 개수 기준)를 자연스럽게 구할 수 있기 때문이다.

Implementing BFS

Data Structures for BFS

BFS를 구현하기 위해 필요한 자료구조는 3가지이다:

bool processed[MAXV+1];   // 이미 완전히 처리된 정점 
bool discovered[MAXV+1];  // 방문은 했지만 아직 다 보지 않은 정점 
int parent[MAXV+1];       // 해당 정점을 방문하기 전의 부모 노드

또한 BFS는 FIFO queue를 이용하므로, 먼저 발견된 노드를 먼저 처리해야 “너비 우선” 순서가 유지된다. 이때 새로운 정점이 발견되면 discovered[y] = true로 표시하고 큐에 추가한다. 즉, queue는 처리할 정점들이 저장되는 to-do list와 같은 존재이다.

Initializing BFS

아래는 탐색을 시작하기 전에 배열을 초기화하는 함수이다.

void bfs(graph *g, int start) {
    queue q;           /* 방문할 정점들을 담는 큐 */
    int v;             /* 현재 방문 중인 정점 */
    int y;             /* 인접(후속) 정점 */
    edgenode *p;       /* 인접 리스트를 순회하기 위한 포인터 */

    /* 초기화 단계 */
    init_queue(&q);            // 큐 초기화
    enqueue(&q, start);        // 시작 정점을 큐에 넣기
    discovered[start] = true;  // 시작 정점을 "발견됨"으로 표시

    /* BFS 메인 루프 */
    while (!empty_queue(&q)) {
        v = dequeue(&q);           // 큐에서 정점을 하나 꺼냄
        process_vertex_early(v);   // 방문 직후 처리 (예: 출력)
        processed[v] = true;       // 완전히 처리된 정점으로 표시

        /* 인접 정점 순회 */
        p = g->edges[v];           // v의 인접 리스트의 첫 노드
        while (p != NULL) {
            y = p->y;              // 인접 정점 번호

            /* 간선 (v, y) 처리 */
            if ((!processed[y]) || g->directed) {
                process_edge(v, y); // 간선 처리 (예: 출력, 트리 생성 등)
            }

            /* 새로운 정점 발견 시 */
            if (!discovered[y]) {
                enqueue(&q, y);          // 큐에 추가
                discovered[y] = true;    // 발견됨 표시
                parent[y] = v;           // BFS 트리 상의 부모 설정
            }

            p = p->next;                 // 다음 인접 정점으로 이동
        }

        process_vertex_late(v);          // 정점 처리 완료 후 작업
    }
}


각주