Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 973dd38

Browse files
committed
Graph: add graph iterator method.
1 parent 1d7c4e6 commit 973dd38

File tree

12 files changed

+3617
-0
lines changed

12 files changed

+3617
-0
lines changed
Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
/**
2+
* C: 邻接表表示的"有向图(List Directed Graph)"
3+
*
4+
* @author skywang
5+
* @date 2014/04/18
6+
*/
7+
8+
#include <stdio.h>
9+
#include <stdlib.h>
10+
#include <malloc.h>
11+
#include <string.h>
12+
13+
#define MAX 100
14+
#define isLetter(a) ((((a)>='a')&&((a)<='z')) || (((a)>='A')&&((a)<='Z')))
15+
#define LENGTH(a) (sizeof(a)/sizeof(a[0]))
16+
17+
// 邻接表中表对应的链表的顶点
18+
typedef struct _ENode
19+
{
20+
int ivex; // 该边所指向的顶点的位置
21+
struct _ENode *next_edge; // 指向下一条弧的指针
22+
}ENode, *PENode;
23+
24+
// 邻接表中表的顶点
25+
typedef struct _VNode
26+
{
27+
char data; // 顶点信息
28+
ENode *first_edge; // 指向第一条依附该顶点的弧
29+
}VNode;
30+
31+
// 邻接表
32+
typedef struct _LGraph
33+
{
34+
int vexnum; // 图的顶点的数目
35+
int edgnum; // 图的边的数目
36+
VNode vexs[MAX];
37+
}LGraph;
38+
39+
/*
40+
* 返回ch在matrix矩阵中的位置
41+
*/
42+
static int get_position(LGraph g, char ch)
43+
{
44+
int i;
45+
for(i=0; i<g.vexnum; i++)
46+
if(g.vexs[i].data==ch)
47+
return i;
48+
return -1;
49+
}
50+
51+
/*
52+
* 读取一个输入字符
53+
*/
54+
static char read_char()
55+
{
56+
char ch;
57+
58+
do {
59+
ch = getchar();
60+
} while(!isLetter(ch));
61+
62+
return ch;
63+
}
64+
65+
/*
66+
* 将node链接到list的末尾
67+
*/
68+
static void link_last(ENode *list, ENode *node)
69+
{
70+
ENode *p = list;
71+
72+
while(p->next_edge)
73+
p = p->next_edge;
74+
p->next_edge = node;
75+
}
76+
77+
/*
78+
* 创建邻接表对应的图(自己输入)
79+
*/
80+
LGraph* create_lgraph()
81+
{
82+
char c1, c2;
83+
int v, e;
84+
int i, p1, p2;
85+
ENode *node1, *node2;
86+
LGraph* pG;
87+
88+
// 输入"顶点数"和"边数"
89+
printf("input vertex number: ");
90+
scanf("%d", &v);
91+
printf("input edge number: ");
92+
scanf("%d", &e);
93+
if ( v < 1 || e < 1 || (e > (v * (v-1))))
94+
{
95+
printf("input error: invalid parameters!\n");
96+
return NULL;
97+
}
98+
99+
if ((pG=(LGraph*)malloc(sizeof(LGraph))) == NULL )
100+
return NULL;
101+
memset(pG, 0, sizeof(LGraph));
102+
103+
// 初始化"顶点数"和"边数"
104+
pG->vexnum = v;
105+
pG->edgnum = e;
106+
// 初始化"邻接表"的顶点
107+
for(i=0; i<pG->vexnum; i++)
108+
{
109+
printf("vertex(%d): ", i);
110+
pG->vexs[i].data = read_char();
111+
pG->vexs[i].first_edge = NULL;
112+
}
113+
114+
// 初始化"邻接表"的边
115+
for(i=0; i<pG->edgnum; i++)
116+
{
117+
// 读取边的起始顶点和结束顶点
118+
printf("edge(%d): ", i);
119+
c1 = read_char();
120+
c2 = read_char();
121+
122+
p1 = get_position(*pG, c1);
123+
p2 = get_position(*pG, c2);
124+
// 初始化node1
125+
node1 = (ENode*)malloc(sizeof(ENode));
126+
node1->ivex = p2;
127+
// 将node1链接到"p1所在链表的末尾"
128+
if(pG->vexs[p1].first_edge == NULL)
129+
pG->vexs[p1].first_edge = node1;
130+
else
131+
link_last(pG->vexs[p1].first_edge, node1);
132+
}
133+
134+
return pG;
135+
}
136+
137+
/*
138+
* 创建邻接表对应的图(用已提供的数据)
139+
*/
140+
LGraph* create_example_lgraph()
141+
{
142+
char c1, c2;
143+
char vexs[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
144+
char edges[][2] = {
145+
{'A', 'B'},
146+
{'B', 'C'},
147+
{'B', 'E'},
148+
{'B', 'F'},
149+
{'C', 'E'},
150+
{'D', 'C'},
151+
{'E', 'B'},
152+
{'E', 'D'},
153+
{'F', 'G'}};
154+
int vlen = LENGTH(vexs);
155+
int elen = LENGTH(edges);
156+
int i, p1, p2;
157+
ENode *node1, *node2;
158+
LGraph* pG;
159+
160+
161+
if ((pG=(LGraph*)malloc(sizeof(LGraph))) == NULL )
162+
return NULL;
163+
memset(pG, 0, sizeof(LGraph));
164+
165+
// 初始化"顶点数"和"边数"
166+
pG->vexnum = vlen;
167+
pG->edgnum = elen;
168+
// 初始化"邻接表"的顶点
169+
for(i=0; i<pG->vexnum; i++)
170+
{
171+
pG->vexs[i].data = vexs[i];
172+
pG->vexs[i].first_edge = NULL;
173+
}
174+
175+
// 初始化"邻接表"的边
176+
for(i=0; i<pG->edgnum; i++)
177+
{
178+
// 读取边的起始顶点和结束顶点
179+
c1 = edges[i][0];
180+
c2 = edges[i][1];
181+
182+
p1 = get_position(*pG, c1);
183+
p2 = get_position(*pG, c2);
184+
// 初始化node1
185+
node1 = (ENode*)malloc(sizeof(ENode));
186+
node1->ivex = p2;
187+
// 将node1链接到"p1所在链表的末尾"
188+
if(pG->vexs[p1].first_edge == NULL)
189+
pG->vexs[p1].first_edge = node1;
190+
else
191+
link_last(pG->vexs[p1].first_edge, node1);
192+
}
193+
194+
return pG;
195+
}
196+
197+
/*
198+
* 深度优先搜索遍历图的递归实现
199+
*/
200+
static void DFS(LGraph G, int i, int *visited)
201+
{
202+
int w;
203+
ENode *node;
204+
205+
visited[i] = 1;
206+
printf("%c ", G.vexs[i].data);
207+
node = G.vexs[i].first_edge;
208+
while (node != NULL)
209+
{
210+
if (!visited[node->ivex])
211+
DFS(G, node->ivex, visited);
212+
node = node->next_edge;
213+
}
214+
}
215+
216+
/*
217+
* 深度优先搜索遍历图
218+
*/
219+
void DFSTraverse(LGraph G)
220+
{
221+
int i;
222+
int visited[MAX]; // 顶点访问标记
223+
224+
// 初始化所有顶点都没有被访问
225+
for (i = 0; i < G.vexnum; i++)
226+
visited[i] = 0;
227+
228+
printf("DFS: ");
229+
for (i = 0; i < G.vexnum; i++)
230+
{
231+
if (!visited[i])
232+
DFS(G, i, visited);
233+
}
234+
printf("\n");
235+
}
236+
237+
/*
238+
* 广度优先搜索(类似于树的层次遍历)
239+
*/
240+
void BFS(LGraph G)
241+
{
242+
int head = 0;
243+
int rear = 0;
244+
int queue[MAX]; // 辅组队列
245+
int visited[MAX]; // 顶点访问标记
246+
int i, j, k;
247+
ENode *node;
248+
249+
for (i = 0; i < G.vexnum; i++)
250+
visited[i] = 0;
251+
252+
printf("BFS: ");
253+
for (i = 0; i < G.vexnum; i++)
254+
{
255+
if (!visited[i])
256+
{
257+
visited[i] = 1;
258+
printf("%c ", G.vexs[i].data);
259+
queue[rear++] = i; // 入队列
260+
}
261+
while (head != rear)
262+
{
263+
j = queue[head++]; // 出队列
264+
node = G.vexs[j].first_edge;
265+
while (node != NULL)
266+
{
267+
k = node->ivex;
268+
if (!visited[k])
269+
{
270+
visited[k] = 1;
271+
printf("%c ", G.vexs[k].data);
272+
queue[rear++] = k;
273+
}
274+
node = node->next_edge;
275+
}
276+
}
277+
}
278+
printf("\n");
279+
}
280+
281+
/*
282+
* 打印邻接表图
283+
*/
284+
void print_lgraph(LGraph G)
285+
{
286+
int i,j;
287+
ENode *node;
288+
289+
printf("List Graph:\n");
290+
for (i = 0; i < G.vexnum; i++)
291+
{
292+
printf("%d(%c): ", i, G.vexs[i].data);
293+
node = G.vexs[i].first_edge;
294+
while (node != NULL)
295+
{
296+
printf("%d(%c) ", node->ivex, G.vexs[node->ivex].data);
297+
node = node->next_edge;
298+
}
299+
printf("\n");
300+
}
301+
}
302+
303+
void main()
304+
{
305+
LGraph* pG;
306+
307+
// 自定义"图"(自己输入数据)
308+
//pG = create_lgraph();
309+
// 采用已有的"图"
310+
pG = create_example_lgraph();
311+
312+
// 打印图
313+
print_lgraph(*pG);
314+
DFSTraverse(*pG);
315+
BFS(*pG);
316+
}

0 commit comments

Comments
 (0)