BFS (너비 우선 탐색)
- 먼저 v를 방문한 후, v에 인접한 정점을 차례로 방문한다.
- 다음으로 두 번째 방문한 정점과 인접한 정점을 방문하고, 이후 세 번째 방문한 정점과 인접한 정점을 방문한다.
- 이 과정을 반복한다.
각 정점을 방문할 때 그에 인접한 정점을 큐에 삽입하고,
다음으로 방문할 정점은 큐에서 삭제하여 얻는다.
(방문: 큐에 저장, visited 원소 값=1)
adjacency list Version (인접 리스트 버전)
#include <stdio.h> #include <stdlib.h> #define MAX_QUEUE_SIZE 10 typedef int element; typedef struct { element data[MAX_QUEUE_SIZE]; int front, rear; }QueueType; typedef QueueType* QueueType_ptr; QueueType q; void qinit(QueueType_ptr q) { q->front = 0; q->rear = 0; } int is_empty(QueueType_ptr q) { if (q->front == q->rear) return 1; else return 0; }; int is_full(QueueType_ptr q) { if ((q->rear + 1) % MAX_QUEUE_SIZE == q->front) return 1; else return 0; } void enqueue(QueueType_ptr q, int item) { if (!is_full(q)) { q->rear = (q->rear + 1) % MAX_QUEUE_SIZE; q->data[q->rear] = item; } else printf("큐가 꽉 찼습니다"); } int dequeue(QueueType_ptr q) { if (!is_empty(q)) { q->front = (q->front + 1) % MAX_QUEUE_SIZE; return q->data[q->front]; } else printf("큐가 비어 있습니다"); } typedef struct GraphNode { int vertex; struct GraphNode* link; }GraphNode; #define MAX_VERTICES 50 typedef struct GraphType { int n; // 정점의 개수 GraphNode* adj_list[MAX_VERTICES]; }GraphType; // 그래프 초기화 void init(GraphType* g) { int v; g->n = 0; for (v = 0; v < MAX_VERTICES; v++) g->adj_list[v] = NULL; } // 정점 삽입 연산 void insert_vertex(GraphType* g, int v) { if ((g->n) + 1 > MAX_VERTICES) { fprintf(stderr, "그래프: 정점의 개수 초과"); return; } g->n++; } // 간선 삽입 연산, v를 u의 인접 리스트에 삽입한다. void insert_edge(GraphType* g, int u, int v) { GraphNode* node; if (u >= g->n || v >= g->n) { fprintf(stderr, "그래프: 정점 번호 오류"); return; } if (g->adj_list[u] == NULL) { // insert_first node = (GraphNode*)malloc(sizeof(GraphNode)); node->vertex = v; node->link = g->adj_list[u]; g->adj_list[u] = node; } else { //insert_last node = g->adj_list[u]; while (node->link != NULL) node = node->link; node->link = (GraphNode*)malloc(sizeof(GraphNode)); node->link->vertex = v; node->link->link = NULL; } } void print_adj_list(GraphType* g) { for (int i = 0; i < g->n; i++) { GraphNode* p = g->adj_list[i]; printf("정정 %d의 인접 리스트", i); while (p != NULL) { printf("-> %d", p->vertex); p = p->link; } printf("\n"); } } // 너비 우선 탐색 (BFS) int visited[MAX_VERTICES]; void BFS(GraphType* g, int v) { GraphNode* w; QueueType_ptr q = (QueueType_ptr)malloc(sizeof(QueueType)); qinit(q); visited[v] = 1; // TRUE printf("%d 방문 -> ", v); enqueue(q, v); while (!is_empty(q)) { v = dequeue(q); for (w = g->adj_list[v]; w; w = w->link) { if (!visited[w->vertex]) { visited[w->vertex] = 1; printf("%d 방문 -> ", w->vertex); enqueue(q, w->vertex); } } } } int main() { GraphType* g; g = (GraphType*)malloc(sizeof(GraphType)); init(g); // 정점 삽입 for (int i = 0; i <= 7; i++) insert_vertex(g, i); // 에지 삽입 // 인접 리스트는 오름차순으로 정렬한다. insert_edge(g,u정점,u랑 인접한 v정점), (v가 작은 순서대로 삽입) insert_edge(g, 0, 1); insert_edge(g, 0, 2); insert_edge(g, 1, 0); insert_edge(g, 1, 3); insert_edge(g, 1, 4); insert_edge(g, 2, 0); insert_edge(g, 2, 5); insert_edge(g, 2, 6); insert_edge(g, 3, 1); insert_edge(g, 3, 7); insert_edge(g, 4, 1); insert_edge(g, 4, 7); insert_edge(g, 5, 2); insert_edge(g, 5, 7); insert_edge(g, 6, 2); insert_edge(g, 6, 7); insert_edge(g, 7, 3); insert_edge(g, 7, 4); insert_edge(g, 7, 5); insert_edge(g, 7, 6); print_adj_list(g); printf("\n너비 우선 탐색\n"); BFS(g, 0); printf("end\n"); free(g); return 0; }
adjacency matrix Version (인접 행렬 버전)
#include <stdio.h> #include <stdlib.h> #define MAX_QUEUE_SIZE 10 typedef int element; typedef struct { element data[MAX_QUEUE_SIZE]; int front, rear; }QueueType; typedef QueueType* QueueType_ptr; QueueType q; void qinit(QueueType_ptr q) { q->front = 0; q->rear = 0; } int is_empty(QueueType_ptr q) { if (q->front == q->rear) return 1; else return 0; }; int is_full(QueueType_ptr q) { if ((q->rear + 1) % MAX_QUEUE_SIZE == q->front) return 1; else return 0; } void enqueue(QueueType_ptr q, int item) { if (!is_full(q)) { q->rear = (q->rear + 1) % 5; q->data[q->rear] = item; } else printf("큐가 꽉 찼습니다"); } int dequeue(QueueType_ptr q) { if (!is_empty(q)) { q->front = (q->front + 1) % 5; return q->data[q->front]; } else printf("큐가 비어 있습니다"); } #define MAX_VERTICES 50 typedef struct GraphType { int n; // 정점의 개수 int adj_mat[MAX_VERTICES][MAX_VERTICES]; }GraphType; // 그래프 초기화 void init(GraphType* g) { int r, c; g->n = 0; for (r = 0; r < MAX_VERTICES; r++) { for (c = 0; c < MAX_VERTICES; c++) g->adj_mat[r][c] = 0; } } // 정점 삽입 연산 void insert_vertex(GraphType* g, int v) { if ((g->n) + 1 > MAX_VERTICES) { fprintf(stderr, "그래프: 정점의 개수 초과"); return; } g->n++; } // 간선 삽입 연산, v를 u의 인접 리스트에 삽입한다. void insert_edge(GraphType* g, int start, int end) { if (start >= g->n || end >= g->n) { fprintf(stderr, "그래프: 정점 번호 오류"); return; } g->adj_mat[start][end] = 1; g->adj_mat[end][start] = 1; } void print_adj_list(GraphType* g) { for (int i = 0; i < g->n; i++) { for (int j = 0; j < g->n; j++) { printf("%2d ", g->adj_mat[i][j]); } printf("\n"); } } // 너비 우선 탐색 (BFS) int visited[MAX_VERTICES]; void BFS(GraphType* g, int v) { int w; QueueType_ptr q = (QueueType_ptr)malloc(sizeof(QueueType)); qinit(q); visited[v] = 1; // TRUE printf("%d 방문 -> ", v); enqueue(q, v); while (!is_empty(q)) { v = dequeue(q); for (w = 0; w < g->n; w++) { if (g->adj_mat[v][w] && !visited[w]) { visited[w] = 1; printf("%d 방문 -> ", w); enqueue(q, w); } } } } int main() { GraphType* g; g = (GraphType*)malloc(sizeof(GraphType)); init(g); // 정점 삽입 for (int i = 0; i <= 7; i++) insert_vertex(g, i); // 에지가 있으면 인접 행렬에 삽입 insert_edge(g, 0, 1); insert_edge(g, 0, 2); insert_edge(g, 1, 3); insert_edge(g, 1, 4); insert_edge(g, 3, 7); insert_edge(g, 4, 7); insert_edge(g, 7, 5); insert_edge(g, 5, 2); insert_edge(g, 2, 6); insert_edge(g, 7, 6); print_adj_list(g); printf("\n너비 우선 탐색\n"); BFS(g, 0); printf("end\n"); free(g); return 0; }