2 001 002 003 004 005 006 007



























![2. 그래프의 구현 : (2) 인접 리스트 – [예제 9 -2] 022 void insert. 2. 그래프의 구현 : (2) 인접 리스트 – [예제 9 -2] 022 void insert.](https://slidetodoc.com/presentation_image_h2/3c89ba01d0dd0721ab31e192f842a7ba/image-28.jpg)



























![3. 그래프 순회 : (1)깊이 우선 탐색 – [예제 9 -3] 044 else { 3. 그래프 순회 : (1)깊이 우선 탐색 – [예제 9 -3] 044 else {](https://slidetodoc.com/presentation_image_h2/3c89ba01d0dd0721ab31e192f842a7ba/image-56.jpg)


























![3. 그래프 순회 : (2)너비 우선 탐색 : [예제 9 -4] 096 097 void 3. 그래프 순회 : (2)너비 우선 탐색 : [예제 9 -4] 096 097 void](https://slidetodoc.com/presentation_image_h2/3c89ba01d0dd0721ab31e192f842a7ba/image-83.jpg)


































- Slides: 117
2. 그래프의 구현 : 001 002 003 004 005 006 배열 007 008 009 010 011 012 013 014 015 016 017 (1) 인접 행렬 – [예제 9 -1] #include <stdio. h> #include <stdlib. h> #define MAX_VERTEX 30 typedef struct graph. Type{ // 그래프를 인접행렬로 표현하기 위한 구조체 정의 int n; // 그래프의 정점의 개수 int adj. Matrix[MAX_VERTEX]; // 그래프에 대한 30 x 30의 2차원 } graph. Type; void create. Graph(graph. Type* g) // 공백 그래프 생성 연산 { int i, j; g->n = 0; // 정점의 개수를 0으로 초기화 for(i=0; i<MAX_VERTEX; i++) { for(j=0; j<MAX_VERTEX; j++) g->adj. Matrix[i][j]=0; // 그래프 g에대한 2차원 배열의 값을 0으로 초기화 } } 17/116
2. 그래프의 구현 : 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 (1) 인접 행렬 – [예제 9 -1] // 그래프 g의 2차원 배열 값을 순서대로 출력하는 연산 void print_adj. Matrix(graph. Type* g) { int i, j; for(i=0; i<(g->n); i++){ printf("ntt"); for(j=0; j<(g->n); j++) printf("%2 d", g->adj. Matrix[i][j]); } } void main() { int i; graph. Type *G 1, *G 2, *G 3, *G 4; G 1 = (graph. Type *)malloc(sizeof(graph. Type)); G 2 = (graph. Type *)malloc(sizeof(graph. Type)); G 3 = (graph. Type *)malloc(sizeof(graph. Type)); G 4 = (graph. Type *)malloc(sizeof(graph. Type)); create. Graph(G 1); create. Graph(G 2); create. Graph(G 3); create. Graph(G 4); for(i=0; i<4; i++) // 그래프 G 1 insert. Vertex(G 1, i); insert. Edge(G 1, 0, 1); 19/116
2. 그래프의 구현 : 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 (1) 인접 행렬 – [예제 9 -1] insert. Edge(G 1, 0, 3); insert. Edge(G 1, 1, 0); insert. Edge(G 1, 1, 2); insert. Edge(G 1, 1, 3); insert. Edge(G 1, 2, 1); insert. Edge(G 1, 2, 3); insert. Edge(G 1, 3, 0); insert. Edge(G 1, 3, 1); insert. Edge(G 1, 3, 2); printf("n G 1의 인접행렬"); print_adj. Matrix(G 1); for(i=0; i<3; i++) // 그래프 G 2 insert. Vertex(G 2, i); insert. Edge(G 2, 0, 1); insert. Edge(G 2, 0, 2); insert. Edge(G 2, 1, 0); insert. Edge(G 2, 1, 2); insert. Edge(G 2, 2, 0); insert. Edge(G 2, 2, 1); printf("nn G 2의 인접행렬"); print_adj. Matrix(G 2); 20/116
2. 그래프의 구현 : 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 (1) 인접 행렬 – [예제 9 -1] for(i=0; i<4; i++) // 그래프 G 3 insert. Vertex(G 3, i); insert. Edge(G 3, 0, 1); insert. Edge(G 3, 0, 3); insert. Edge(G 3, 1, 2); insert. Edge(G 3, 1, 3); insert. Edge(G 3, 2, 3); printf("nn G 3의 인접행렬"); print_adj. Matrix(G 3); for(i=0; i<3; i++) // 그래프 G 4 insert. Vertex(G 4, i); insert. Edge(G 4, 0, 1); insert. Edge(G 4, 0, 2); insert. Edge(G 4, 1, 0); insert. Edge(G 4, 1, 2); printf("nn G 4의 인접행렬"); print_adj. Matrix(G 4); getchar(); } 21/116
2. 그래프의 구현 : (2) 인접 리스트 – [예제 9 -2] 022 void insert. Vertex(graph. Type* g, int v) // 그래프 g에 정점 v를 삽입하는 연산 023 { 024 if(((g->n)+1)>MAX_VERTEX){ 025 printf("n 그래프 정점의 개수를 초과하였습니다!"); 026 return; 027 } 028 g->n++; 029 } 030 031 void insert. Edge(graph. Type* g, int u, int v) // 그래프g에 간선 (u, v)를 삽입하 는 연산 032 { 033 graph. Node* node; 034 if(u>=g->n || v>=g->n) { 035 printf("n 그래프에 없는 정점입니다!"); 036 return; 037 } 038 node = (graph. Node *)malloc(sizeof(graph. Node)); 039 node->vertex = v; 040 node->link = g->adj. List_H[u]; 041 g->adj. List_H[u] = node; 28/116 042 }
2. 그래프의 구현 : 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 (2) 인접 리스트 – [예제 9 -2] void print_adj. List(graph. Type* g) // 그래프 g의 각 정점에 대한 인접 리스트를 출력하는 연산 { int i; graph. Node* p; for(i=0; i<g->n; i++){ printf("ntt정점 %c의 인접 리스트", i+65); p= g->adj. List_H[i]; while(p){ printf(" -> %c", p->vertex +65); //정점 0~3을 A~D로 출력 p = p->link; } } } 29/116
2. 그래프의 구현 : 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 (2) 인접 리스트 – [예제 9 -2] void main() { int i; graph. Type *G 1, *G 2, *G 3, *G 4; G 1 = (graph. Type *)malloc(sizeof(graph. Type)); G 2 = (graph. Type *)malloc(sizeof(graph. Type)); G 3 = (graph. Type *)malloc(sizeof(graph. Type)); G 4 = (graph. Type *)malloc(sizeof(graph. Type)); create. Graph(G 1); create. Graph(G 2); create. Graph(G 3); create. Graph(G 4); for(i=0; i<4; i++) // 그래프 G 1 insert. Vertex(G 1, i); insert. Edge(G 1, 0, 3); insert. Edge(G 1, 0, 1); insert. Edge(G 1, 1, 3); insert. Edge(G 1, 1, 2); insert. Edge(G 1, 1, 0); insert. Edge(G 1, 2, 3); insert. Edge(G 1, 2, 1); insert. Edge(G 1, 3, 2); insert. Edge(G 1, 3, 1); insert. Edge(G 1, 3, 0); 30/116
2. 그래프의 구현 : 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 (2) 인접 리스트 – [예제 9 -2] printf("n G 1의 인접 리스트"); print_adj. List(G 1); for(i=0; i<3; i++) // 그래프 G 2 insert. Vertex(G 2, i); insert. Edge(G 2, 0, 2); insert. Edge(G 2, 0, 1); insert. Edge(G 2, 1, 2); insert. Edge(G 2, 1, 0); insert. Edge(G 2, 2, 1); insert. Edge(G 2, 2, 0); printf("nn G 2의 인접 리스트"); print_adj. List(G 2); for(i=0; i<4; i++) // 그래프 G 3 insert. Vertex(G 3, i); insert. Edge(G 3, 0, 3); insert. Edge(G 3, 0, 1); insert. Edge(G 3, 1, 3); insert. Edge(G 3, 1, 2); insert. Edge(G 3, 2, 3); printf("nn G 3의 인접 리스트"); print_adj. List(G 3); 31/116
2. 그래프의 구현 : 102 103 104 105 106 107 108 109 110 111 112 113 (2) 인접 리스트 – [예제 9 -2] for(i=0; i<3; i++) // 그래프 G 4 insert. Vertex(G 4, i); insert. Edge(G 4, 0, 2); insert. Edge(G 4, 0, 1); insert. Edge(G 4, 1, 2); insert. Edge(G 4, 1, 0); printf("nn G 4의 인접 리스트"); print_adj. List(G 4); getchar(); } 32/116
3. 그래프 순회 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 : (1)깊이 우선 탐색 – [예제 9 -3] #include <stdio. h> #include <memory. h> #include <stdlib. h> #define MAX_VERTEX 10 #define FALSE 0 #define TRUE 1 typedef struct graph. Node{ int vertex; struct graph. Node* link; } graph. Node; // 그래프에 대한 인접 리스트의 노드 구조 정의 typedef struct graph. Type{ int n; // 정점의 갯수 graph. Node* adj. List_H[MAX_VERTEX]; // 정점에 대한 인접 리스트의 헤드 노드 배열 int visited[MAX_VERTEX]; // 정점에 대한 방문 표시를 위한 배열 } graph. Type; //// << 스택 연산 typedef struct stack. Node { int data; struct stack. Node *link; }stack. Node; 54/116
3. 그래프 순회 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 : (1)깊이 우선 탐색 – [예제 9 -3] stack. Node* top; void push(int item) { stack. Node* temp=(stack. Node *)malloc(sizeof(stack. Node)); temp->data = item; temp->link = top; top = temp; } int pop() { int item; stack. Node* temp=top; if(top == NULL) { printf("nn Stack is empty !n"); return 0; } 55/116
3. 그래프 순회 : (1)깊이 우선 탐색 – [예제 9 -3] 044 else { 045 item = temp->data; 046 top = temp->link; 047 free(temp); 048 return item; 049 } 050 } 051 //// 스택 연산 >> 052 053 void create. Graph(graph. Type* g) // 깊이 우선 탐색을 위한 초기 공백 그래프 생성 연산 054 { 055 int v; 056 g->n = 0; // 그래프의 정점 개수를 0으로 초기화 057 for(v=0; v<MAX_VERTEX; v++){ 058 g->visited[v] = FALSE; // 그래프의 정점에 대한 배열 visited를 FALSE로 초기화 059 g->adj. List_H[v]=NULL; // 인접리스트에대한헤드노드배열을 NULL로초기화 060 } 061 } 062 56/116
3. 그래프 순회 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 : (1)깊이 우선 탐색 – [예제 9 -3] void insert. Vertex(graph. Type* g, int v) // 그래프 g에 정점 v를 삽입하는 연산 { if(((g->n)+1)>MAX_VERTEX){ printf("n 그래프 정점의 개수를 초과하였습니다!"); return; } g->n++; } void insert. Edge(graph. Type* g, int u, int v) // 그래프 g에 간선 (u, v)를 삽입하는 연산 { graph. Node* node; if(u>=g->n || v>=g->n) { printf("n 그래프에 없는 정점입니다!"); return; } node = (graph. Node *)malloc(sizeof(graph. Node)); node->vertex = v; node->link = g->adj. List_H[u]; g->adj. List_H[u] = node; } 57/116
3. 그래프 순회 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 : (1)깊이 우선 탐색 – [예제 9 -3] void print_adj. List(graph. Type* g) // 그래프 g에 대한 인접 리스트를 출력하는 연산 { int i; graph. Node* p; for(i=0; i<g->n; i++){ printf("ntt정점%c의 인접 리스트", i +65); p= g->adj. List_H[i]; while(p){ printf(" -> %c", p->vertex +65); p = p->link; } } } 58/116
3. 그래프 순회 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 : (1)깊이 우선 탐색 – [예제 9 -3] void main() { int i; graph. Type *G 9; G 9 = (graph. Type *)malloc(sizeof(graph. Type)); create. Graph(G 9); for(i=0; i<7; i++) // 그래프 G 9 구성 insert. Vertex(G 9, i); insert. Edge(G 9, 0, 2); insert. Edge(G 9, 0, 1); insert. Edge(G 9, 1, 4); insert. Edge(G 9, 1, 3); insert. Edge(G 9, 1, 0); insert. Edge(G 9, 2, 4); insert. Edge(G 9, 2, 0); insert. Edge(G 9, 3, 6); insert. Edge(G 9, 3, 1); insert. Edge(G 9, 4, 6); insert. Edge(G 9, 4, 2); insert. Edge(G 9, 4, 1); insert. Edge(G 9, 5, 6); 60/116
3. 그래프 순회 144 145 146 147 148 149 150 151 152 153 154 : (1)깊이 우선 탐색 – [예제 9 -3] insert. Edge(G 9, 6, 5); insert. Edge(G 9, 6, 4); insert. Edge(G 9, 6, 3); printf("n G 9의 인접 리스트 "); print_adj. List(G 9); printf("nn////////nn깊이 우선 탐색 >> "); DFS_adj. List(G 9, 0); // 0번 정점인 정점 A에서 깊이 우선 탐색 시작 getchar(); } 61/116
3. 그래프 순회 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 : (2)너비 우선 탐색 : [예제 9 -4] #include <stdio. h> #include <memory. h> #include <stdlib. h> #define MAX_VERTEX 10 #define FALSE 0 #define TRUE 1 typedef struct graph. Node{ int vertex; struct graph. Node* link; } graph. Node; // 그래프에 대한 인접 리스트의 노드 구조 정의 typedef struct graph. Type{ int n; // 정점의 개수 graph. Node* adj. List_H[MAX_VERTEX]; // 정점에 대한 인접 리스트의 헤드 노드 배열 int visited[MAX_VERTEX]; // 정점에 대한 방문 표시를 위한 배열 } graph. Type; 016 017 018 019 //// << 큐 연산 020 typedef struct QNode{ 021 int data; 022 struct QNode *link; 023 } QNode; 78/116
3. 그래프 순회 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 : (2)너비 우선 탐색 : [예제 9 -4] typedef struct{ QNode *front, *rear; } LQueue. Type; LQueue. Type *create. Linked. Queue() { LQueue. Type *LQ; LQ = (LQueue. Type *)malloc(sizeof(LQueue. Type)); LQ->front=NULL; LQ->rear=NULL; return LQ; } int is. Empty(LQueue. Type *LQ) { if (LQ->front == NULL) { printf("n Linked Queue is empty! n"); return 1; } else return 0; } 79/116
3. 그래프 순회 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 : (2)너비 우선 탐색 : [예제 9 -4] void en. Queue(LQueue. Type *LQ, int item) { QNode *new. Node=(QNode *)malloc(sizeof(QNode)); new. Node->data = item; new. Node->link = NULL; if(LQ->front == NULL) { LQ->front = new. Node; LQ->rear = new. Node; } else { LQ->rear->link = new. Node; LQ->rear = new. Node; } } 80/116
3. 그래프 순회 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 : (2)너비 우선 탐색 : [예제 9 -4] int de. Queue(LQueue. Type *LQ) { QNode *old = LQ->front; int item; if (is. Empty(LQ)) return 0; else { item = old->data; LQ->front = LQ->front->link; if(LQ->front == NULL) LQ->rear = NULL; free(old); return item; } } 81/116
3. 그래프 순회 : (2)너비 우선 탐색 : [예제 9 -4] 096 097 void insert. Edge(graph. Type* g, int u, int v) // 그래프 g에 간선 (u, v)를 삽입하는 연산 098 { 099 graph. Node* node; 100 if(u>=g->n || v>=g->n) { 101 printf("n 그래프에 없는 정점입니다!"); 102 return; 103 } 104 node = (graph. Node *)malloc(sizeof(graph. Node)); 105 node->vertex = v; 106 node->link = g->adj. List_H[u]; 107 g->adj. List_H[u] = node; 108 } 109 83/116
3. 그래프 순회 110 111 112 113 114 115 116 117 118 119 120 121 122 123 : (2)너비 우선 탐색 : [예제 9 -4] void print_adj. List(graph. Type* g) // 그래프 g에 대한 인접리스트를 출력하는 연산 { int i; graph. Node* p; for(i=0; i<g->n; i++){ printf("ntt정점 %c의 인접 리스트", i +65); p= g->adj. List_H[i]; while(p){ printf(" -> %c", p->vertex +65); p = p->link; } } } 84/116
3. 그래프 순회 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 } 142 : (2)너비 우선 탐색 : [예제 9 -4] void BFS_adj. List(graph. Type* g, int v) BFS_adj. List // 그래프 g에서 정점 v에 대한 너비우선 탐색 연산 { graph. Node* w; LQueue. Type* Q; //큐 Q = create. Linked. Queue(); g->visited[v] = TRUE; printf(" %c", v +65); en. Queue(Q, v); while(! is. Empty(Q)){ v=de. Queue(Q); for(w=g->adj. List_H[v]; w; w=w->link) // 인접 정점이 있는 동안 수행 if (!g->visited[w->vertex]){ // 정점 w가 방문하지 않은 정점인 경우 g->visited[w->vertex] = TRUE; printf(" %c", w->vertex +65); // 정점 0~6을 A~G로 바꾸어서 출력 en. Queue(Q, w->vertex); } } 85/116
3. 그래프 순회 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 : (2)너비 우선 탐색 : [예제 9 -4] void main() { int i; graph. Type *G 9; G 9 = (graph. Type *)malloc(sizeof(graph. Type)); create. Graph(G 9); for(i=0; i<7; i++) // 그래프 G 9 구성 insert. Vertex(G 9, i); insert. Edge(G 9, 0, 2); insert. Edge(G 9, 0, 1); insert. Edge(G 9, 1, 4); insert. Edge(G 9, 1, 3); insert. Edge(G 9, 1, 0); insert. Edge(G 9, 2, 4); insert. Edge(G 9, 2, 0); insert. Edge(G 9, 3, 6); insert. Edge(G 9, 3, 1); 86/116
3. 그래프 순회 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 } : (2)너비 우선 탐색 : [예제 9 -4] insert. Edge(G 9, 4, 6); insert. Edge(G 9, 4, 2); insert. Edge(G 9, 4, 1); insert. Edge(G 9, 5, 6); insert. Edge(G 9, 6, 5); insert. Edge(G 9, 6, 4); insert. Edge(G 9, 6, 3); printf("n G 9의 인접 리스트 "); print_adj. List(G 9); printf("nn////////nn너비 우선 탐색 >> "); BFS_adj. List(G 9, 0); // 0번 정점인 정점 A에서 너비 우선 탐색 시작 getchar(); 87/116










































































































