2 001 002 003 004 005 006 007

  • Slides: 117
Download presentation

2. 그래프의 구현 : 001 002 003 004 005 006 배열 007 008 009

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

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

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

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.

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

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

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

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

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

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

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 {

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

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

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

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

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

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

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

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

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

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

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

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

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

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