메뉴 여닫기
환경 설정 메뉴 여닫기
개인 메뉴 여닫기
로그인하지 않음
지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

BFS: 두 판 사이의 차이

noriwiki
Pinkgo (토론 | 기여)
 
Pinkgo (토론 | 기여)
4번째 줄: 4번째 줄:


==개요==
==개요==
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가지이다:
<syntaxhighlight lang="c">
bool processed[MAXV+1];  // 이미 완전히 처리된 정점
bool discovered[MAXV+1];  // 방문은 했지만 아직 다 보지 않은 정점
int parent[MAXV+1];      // 해당 정점을 방문하기 전의 부모 노드
</syntaxhighlight>
또한 BFS는 FIFO queue를 이용하므로, 먼저 발견된 노드를 먼저 처리해야 “너비 우선” 순서가 유지된다. 이때 새로운 정점이 발견되면 discovered[y] = true로 표시하고 큐에 추가한다. 즉, queue는 처리할 정점들이 저장되는 to-do list와 같은 존재이다.
===Initializing BFS===
아래는 탐색을 시작하기 전에 배열을 초기화하는 함수이다.
<syntaxhighlight lang="c">
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);          // 정점 처리 완료 후 작업
    }
}
</syntaxhighlight>
<syntaxhighlight lang="c">
</syntaxhighlight>
<syntaxhighlight lang="c">
</syntaxhighlight>
<syntaxhighlight lang="c">
</syntaxhighlight>
<syntaxhighlight lang="c">
</syntaxhighlight>
<syntaxhighlight lang="c">
</syntaxhighlight>
<syntaxhighlight lang="c">
</syntaxhighlight>


==각주==
==각주==

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);          // 정점 처리 완료 후 작업
    }
}


각주