-
Notifications
You must be signed in to change notification settings - Fork 0
/
practice8_3.c
166 lines (147 loc) · 3.96 KB
/
practice8_3.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#define MAX_VERTEX 10
#define FALSE 0
#define TRUE 1
// 그래프에 대한 인접 리스트의 노드 구조 정의
typedef struct graphNode {
int vertex;
struct graphNode* link;
} graphNode;
typedef struct graphType {
int n; // 정점 개수
graphNode* adjList_H[MAX_VERTEX]; // 정점에 대한 인접 리스트의 헤드 노드 배열
int visited[MAX_VERTEX]; // 정점에 대한 방문 표시를 위한 배열
} graphType;
// << 스택 (5장에서 설명한 연결 리스트를 이용한 스택 연산 수행:[예제 5-2]의 05~43행과 동일)
typedef int element;
typedef struct stackNode {
int data;
struct stackNode *link;
} stackNode;
stackNode* top;
// 스택이 공백인지 확인하는 연산
int isEmpty() {
if (top == NULL) return 1;
else return 0;
}
void push(int item) {
stackNode* temp = (stackNode *)malloc(sizeof(stackNode));
temp->data = item;
temp->link = top;
top = temp;
}
int pop() {
int item;
stackNode* temp = top;
if (isEmpty()) {
printf("\n\n Stack is empty !\n");
return 0;
}
else {
item = temp->data;
top = temp->link;
free(temp);
return item;
}
} // 스택 >>
// 깊이 우선 탐색을 위해 초기 공백 그래프를 생성하는 연산
void createGraph(graphType* g) {
int v;
g->n = 0; // 그래프의 정점 개수를 0으로 초기화
for (v = 0; v<MAX_VERTEX; v++) {
g->visited[v] = FALSE; // 그래프의 정점에 대한 배열 visited를 FALSE로 초기화
g->adjList_H[v] = NULL; // 인접 리스트에 대한 헤드 노드 배열을 NULL로 초기화
}
}
// 그래프 g에 정점 v를 삽입하는 연산 : [예제 8-2]의 26~32행과 동일
void insertVertex(graphType* g, int v) {
if (((g->n) + 1)>MAX_VERTEX) {
printf("\n 그래프 정점의 개수를 초과하였습니다!");
return;
}
g->n++;
}
// 그래프 g에 간선 (u, v)를 삽입하는 연산 : [예제 8-2]의 35~47행과 동일
void insertEdge(graphType* g, int u, int v) {
graphNode* node;
if (u >= g->n || v >= g->n) {
printf("\n 그래프에 없는 정점입니다!");
return;
}
node = (graphNode *)malloc(sizeof(graphNode));
node->vertex = v;
node->link = g->adjList_H[u];
g->adjList_H[u] = node;
}
// 그래프 g의 각 정점에 대한 인접 리스트를 출력하는 연산 : [예제 8-2]의 50~61행과 동일
void print_adjList(graphType* g) {
int i;
graphNode* p;
for (i = 0; i<g->n; i++) {
printf("\n\t\t정점%c의 인접 리스트", i + 65);
p = g->adjList_H[i];
while (p) {
printf(" -> %c", p->vertex + 65);
p = p->link;
}
}
}
// 그래프 g에서 정점 v에 대한 깊이 우선 탐색 연산
void DFS_adjList(graphType* g, int v) {
graphNode* w;
top = NULL; // 스택의 top 설정
push(v); // 깊이 우선 탐색을 시작하는 정점 v를 스택에 push
g->visited[v] = TRUE; // 정점 v를 방문했으므로 해당 배열 값을 TRUE로 설정
printf(" %c", v + 65);
// 스택이 공백이 아닌 동안 깊이 우선 탐색 반복
while (!isEmpty()) {
v = pop();
w = g->adjList_H[v];
// 인접 정점이 있는 동안 수행
while (w) {
// 현재 정점 w를 방문하지 않은 경우
if (!g->visited[w->vertex]) {
if(isEmpty()) push(v); //** 정점v로 돌아올 경우를 위해 다시 push하여 저장
push(w->vertex); // 현재 정점 w를 스택에 push
g->visited[w->vertex] = TRUE; // 정점 w에 대한 배열 값을 TRUE로 설정
printf(" %c", w->vertex + 65); // 정점 0~6을 A~G로 바꾸어서 출력
v = w->vertex;
w = g->adjList_H[v];
}
// 현재 정점 w가 이미 방문된 경우
else w = w->link;
}//while(w)
} //스택이 공백이면 깊이 우선 탐색 종료
}
void main() {
int i;
graphType *G9;
G9 = (graphType *)malloc(sizeof(graphType));
createGraph(G9);
// 그래프 G9 구성
for (i = 0; i<7; i++)
insertVertex(G9, i);
insertEdge(G9, 0, 2);
insertEdge(G9, 0, 1);
insertEdge(G9, 1, 4);
insertEdge(G9, 1, 3);
insertEdge(G9, 1, 0);
insertEdge(G9, 2, 4);
insertEdge(G9, 2, 0);
insertEdge(G9, 3, 6);
insertEdge(G9, 3, 1);
insertEdge(G9, 4, 6);
insertEdge(G9, 4, 2);
insertEdge(G9, 4, 1);
insertEdge(G9, 5, 6);
insertEdge(G9, 6, 5);
insertEdge(G9, 6, 4);
insertEdge(G9, 6, 3);
printf("\n G9의 인접 리스트 ");
print_adjList(G9);
printf("\n\n///////////////\n\n깊이 우선 탐색 >> ");
DFS_adjList(G9, 0); // 0번 정점인 정점 A에서 깊이 우선 탐색 시작
getchar();
}