28 #define STRSIZ BUFSIZ/128
29 #define MESSIZ BUFSIZ/4
32 #define ERR_VTX_OR_EDGE_MISSING -2
33 #define ERR_VTX_NOT_ISOL -3
48 #define NR_OF_TASKNODES 9
49 #define NR_OF_NETNODES 6
51 #define INITIAL_INFO "--- INITIAL DEMO INFORMATION ---\n\nThis demo contains code from the book - \"K Loudon: Mastering Algoritms with C\".\n\nFor further details - check the following:\n\n - \"Chapter 11: Graphs\"\n - The \"graph\" subfolder - in downloadable example zipfile\n\nTip: Use paper/pencil to draw initial graphs - and their calculated results.\nCould be useful here :-)..\n\n"
53 #define MAIN_MENU_ROW "--- GRAPH BASIC USAGE & BFS/DFS DEMO ---\nMENU: 0=Exit 1=Basic_Graph_Usage 2=BFS/Hop_Count 3=DFS/Topological_Sort\nSelection "
57 enum err {err_dupl, err_vtx_or_edge_missing, err_vtx_not_isol, err_fatal, no_err};
58 char err_mess[][MESSIZ] = {
"\n\nError: Duplicate vertex or edge!",
59 "\n\nError: Vertex or edge not found!",
60 "\n\nError: Vertex not isolated - can't be removed!",
61 "\n\nError: Fatal error!",
62 "\n\nEverything is OK"};
64 int net_nodes[NR_OF_NETNODES] = {1, 2, 3, 4, 5, 6};
65 int net_connections[NR_OF_NETNODES][NR_OF_NETNODES] =
66 {{0,1,1,0,0,0}, {1,0,1,1,0,0}, {1,1,0,0,1,0},
67 {0,1,0,0,1,0}, {0,0,1,1,0,1}, {0,0,0,0,1,0}};
70 char task_nodes[NR_OF_TASKNODES] = {
'a',
'b',
'c',
73 char task_connections[NR_OF_TASKNODES][NR_OF_TASKNODES] =
74 {{0,1,1,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,1},
75 {0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,1,0,1,0}, {0,0,1,0,0,0,0,1,0},
76 {0,0,0,0,0,0,0,1,0}, {0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0}};
80 void prt_bas_vtx(
const void *data);
81 void prt_bas_edge(
const void *data);
82 static int bas_match(
const void *str1,
const void *str2);
83 void print_info(
Graph gr,
void (*vtxprt)(
const void *data),
void (*edgprt)(
const void *data));
84 void print_insedge_errmess(
int errcode);
85 void print_remedge_errmess(
int errcode);
86 void print_insvtx_errmess(
int errcode);
87 void print_remvtx_errmess(
int errcode);
88 void print_errmess(
int errcode);
91 void bfs_destroy(
void *data);
92 void prt_bfs_vtx(
const void *data);
93 void prt_bfs_edge(
const void *data);
94 int bfs_match(
const void *k1,
const void *k2);
95 int read_netnodes(
Graph gr,
int *pnodes,
int nr_of_nodes);
96 int read_netconnections(
Graph gr,
int netconn[][NR_OF_NETNODES],
int nr_of_nodes);
99 void dfs_destroy(
void *data);
100 void prt_dfs_vtx(
const void *data);
101 void prt_dfs_edge(
const void *data);
102 int dfs_match(
const void *k1,
const void *k2);
103 int read_tasknodes(
Graph gr,
char *pnodes,
int nr_of_nodes);
104 int read_taskconnections(
Graph gr,
char taskconn[][NR_OF_TASKNODES],
int nr_of_nodes);
109 void prt_bas_vtx(
const void *data)
111 printf(
"%s", (
char *)data);
115 void prt_bas_edge(
const void *data)
117 printf(
"%s ", (
char *)data);
120 static int bas_match(
const void *str1,
const void *str2)
122 return !strcmp((
const char *)str1, (
const char *)str2);
126 void print_info(
Graph gr,
void (*vtxprt)(
const void *data),
void (*edgprt)(
const void *data))
129 printf(
"--- BASIC GRAPH OPERATIONS ---\n");
135 void print_errmess(
int errcode)
142 case ERR_VTX_OR_EDGE_MISSING:
145 case ERR_VTX_NOT_ISOL:
158 void print_testmess(
int testcode)
161 printf(
"\n\nVertices ARE adjacent..");
163 printf(
"\n\nVertices are NOT adjacent..");
172 char data[STRSIZ], *pdata1, *pdata2;
179 printf(
"--- BASIC GRAPH USAGE ---\n\nGraph created.. - let's do some basic graph editing..");
184 if ((pdata1 = (
char *)malloc(STRSIZ)) == NULL)
187 sprintf(mess,
"\n\nInsert first vertex: %s", pdata1);
192 print_info(gr, prt_bas_vtx, prt_bas_edge);
195 if ((pdata1 = (
char *)malloc(STRSIZ)) == NULL)
198 sprintf(mess,
"\n\nInsert vertex: %s", pdata1);
203 print_info(gr, prt_bas_vtx, prt_bas_edge);
206 if ((pdata1 = (
char *)malloc(STRSIZ)) == NULL)
209 sprintf(mess,
"\n\nInsert vertex: %s", pdata1);
214 print_info(gr, prt_bas_vtx, prt_bas_edge);
217 if ((pdata1 = (
char *)malloc(STRSIZ)) == NULL)
220 sprintf(mess,
"\n\nInsert vertex: %s", pdata1);
225 print_info(gr, prt_bas_vtx, prt_bas_edge);
228 if ((pdata1 = (
char *)malloc(STRSIZ)) == NULL)
231 sprintf(mess,
"\n\nInsert vertex: %s", pdata1);
236 print_info(gr, prt_bas_vtx, prt_bas_edge);
242 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
246 sprintf(mess,
"\nNow - let's insert edge: %s --> %s", data, pdata2);
251 print_info(gr, prt_bas_vtx, prt_bas_edge);
254 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
258 sprintf(mess,
"\n\nInsert edge: %s --> %s", data, pdata2);
263 print_info(gr, prt_bas_vtx, prt_bas_edge);
266 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
270 sprintf(mess,
"\n\nInsert edge: %s --> %s", data, pdata2);
275 print_info(gr, prt_bas_vtx, prt_bas_edge);
278 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
282 sprintf(mess,
"\n\nInsert edge: %s --> %s", data, pdata2);
287 print_info(gr, prt_bas_vtx, prt_bas_edge);
290 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
294 sprintf(mess,
"\n\nInsert edge: %s --> %s", data, pdata2);
299 print_info(gr, prt_bas_vtx, prt_bas_edge);
302 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
306 sprintf(mess,
"\n\nInsert edge: %s --> %s", data, pdata2);
311 print_info(gr, prt_bas_vtx, prt_bas_edge);
314 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
318 sprintf(mess,
"\n\nInsert edge: %s --> %s", data, pdata2);
323 print_info(gr, prt_bas_vtx, prt_bas_edge);
326 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
330 sprintf(mess,
"\n\nInsert edge: %s --> %s", data, pdata2);
335 print_info(gr, prt_bas_vtx, prt_bas_edge);
338 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
342 sprintf(mess,
"\n\nInsert edge: %s --> %s", data, pdata2);
347 print_info(gr, prt_bas_vtx, prt_bas_edge);
350 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
354 sprintf(mess,
"\n\nInsert edge: %s --> %s", data, pdata2);
359 print_info(gr, prt_bas_vtx, prt_bas_edge);
363 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
368 sprintf(mess,
"\n\nRemove edge %s --> %s", data, pdata2);
377 print_info(gr, prt_bas_vtx, prt_bas_edge);
383 sprintf(mess,
"\n\nRemove edge %s --> %s", data, pdata2);
392 print_info(gr, prt_bas_vtx, prt_bas_edge);
398 sprintf(mess,
"\n\nRemove edge %s --> %s", data, pdata2);
407 print_info(gr, prt_bas_vtx, prt_bas_edge);
413 sprintf(mess,
"\n\nRemove edge %s --> %s", data, pdata2);
422 print_info(gr, prt_bas_vtx, prt_bas_edge);
428 sprintf(mess,
"\n\nRemove edge %s --> %s", data, pdata2);
438 print_info(gr, prt_bas_vtx, prt_bas_edge);
443 sprintf(mess,
"\n\nRemove vertex %s", data);
449 print_info(gr, prt_bas_vtx, prt_bas_edge);
453 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
457 sprintf(mess,
"\n\nNow - try to insert an invalid edge from %s --> %s", data, pdata2);
463 print_info(gr, prt_bas_vtx, prt_bas_edge);
464 print_errmess(retval);
467 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
471 sprintf(mess,
"\nInsert an existing edge from %s --> %s", data, pdata2);
477 print_info(gr, prt_bas_vtx, prt_bas_edge);
478 print_errmess(retval);
481 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
487 sprintf(mess,
"\nRemove an invalid edge from %s --> %s", data, pdata2);
497 print_info(gr, prt_bas_vtx, prt_bas_edge);
498 print_errmess(retval);
501 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
507 sprintf(mess,
"\nRemoving an invalid edge from %s --> %s", data, pdata2);
517 print_info(gr, prt_bas_vtx, prt_bas_edge);
518 print_errmess(retval);
521 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
525 sprintf(mess,
"\nInsert an existing vertex %s", data);
530 print_info(gr, prt_bas_vtx, prt_bas_edge);
531 print_errmess(retval);
534 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
539 sprintf(mess,
"\nRemove an existing vertex %s", pdata1);
549 print_info(gr, prt_bas_vtx, prt_bas_edge);
550 print_errmess(retval);
553 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
558 sprintf(mess,
"\nRemove an existing vertex %s", pdata1);
568 print_info(gr, prt_bas_vtx, prt_bas_edge);
569 print_errmess(retval);
573 if ((pdata2 = (
char *)malloc(STRSIZ)) == NULL)
578 sprintf(mess,
"\nTest if (%s, %s) are adjacent...", data, pdata2);
581 print_info(gr, prt_bas_vtx, prt_bas_edge);
582 print_testmess(retval);
588 sprintf(mess,
"\n\nTest if (%s, %s) are adjacent...", data, pdata2);
591 print_info(gr, prt_bas_vtx, prt_bas_edge);
592 print_testmess(retval);
598 sprintf(mess,
"\n\nTest if (%s, %s) are adjacent...", data, pdata2);
601 print_info(gr, prt_bas_vtx, prt_bas_edge);
602 print_testmess(retval);
608 sprintf(mess,
"\n\nTest if (%s, %s) are adjacent...", data, pdata2);
611 print_info(gr, prt_bas_vtx, prt_bas_edge);
612 print_testmess(retval);
619 sprintf(mess,
"\n\nFinally - print vertices adjacent to %s: ", data);
623 printf(
"\nVertices adjacent(=incident) from %s (%d pcs): ", data,
GRAPHgetedgecount(vnode));
631 sprintf(mess,
"\n\nTime to tidy up..");
640 void bfs_destroy(
void *data)
647 void prt_bfs_vtx(
const void *data)
653 void prt_bfs_edge(
const void *data)
659 int bfs_match(
const void *k1,
const void *k2)
665 int read_netnodes(
Graph gr,
int *pnodes,
int nr_of_nodes)
670 for (i = 0; i < nr_of_nodes; ++i)
675 bfs->
data = (
int *)malloc(
sizeof(
int));
679 *((
int *)bfs->
data) = *(pnodes+i);
693 int read_netconnections(
Graph gr,
int netconn[][NR_OF_NETNODES],
int nr_of_nodes)
695 int i, j, tmp, retval;
699 for (i = 0; i < nr_of_nodes; ++i)
701 for (j = 0; j < nr_of_nodes; ++j)
703 if (netconn[i][j] != 0)
708 bfs->data = (
int *)malloc(
sizeof(
int));
711 *(
int *)bfs->data = j+1;
739 printf(
"--- NETWORK HOPS/BFS DEMO ---");
744 if ((read_netnodes(gr, net_nodes, NR_OF_NETNODES)) != OK)
746 fprintf(stderr,
"Fatal error when reading netnode data - bailing out..");
751 if ((read_netconnections(gr, net_connections, NR_OF_NETNODES)) != OK)
753 fprintf(stderr,
"Fatal error when reading netconnections data - bailing out..");
765 tmpid =
read_int(
"\nEnter startnode id ", 1, 6);
766 bfstmp.data = &tmpid;
768 if ((retval =
ALGObfs(gr, &bfstmp, &network, bfs_match)) != OK)
770 fprintf(stderr,
"\nFatal error when calling 'ALGObfs()'(Return value: %d) - Bailing out..", retval);
775 printf(
"\nNetwork Hops(BFS Analysis)\n--------------------------");
779 printf(
"\nNode%02d, color=%d, hops=%d", *(
int *)netdata->data, netdata->color, netdata->hops);
791 void dfs_destroy(
void *data)
798 void prt_dfs_vtx(
const void *data)
804 void prt_dfs_edge(
const void *data)
810 int dfs_match(
const void *k1,
const void *k2)
816 int read_tasknodes(
Graph gr,
char *pnodes,
int nr_of_nodes)
821 for (i = 0; i < nr_of_nodes; ++i)
826 dfs->
data = (
char *)malloc(
sizeof(
char));
830 *((
char *)dfs->
data) = *(pnodes+i);
845 int read_taskconnections(
Graph gr,
char taskconn[][NR_OF_TASKNODES],
int nr_of_nodes)
847 int i, j, tmp, retval;
851 for (i = 0; i < nr_of_nodes; ++i)
853 for (j = 0; j < nr_of_nodes; ++j)
855 if (taskconn[i][j] != 0)
860 dfs->data = (
char *)malloc(
sizeof(
char));
863 *(
char *)dfs->data =
'a'+j;
890 printf(
"--- TOPOLOGICAL SORTING/DFS DEMO ---");
895 if ((read_tasknodes(gr, task_nodes, NR_OF_TASKNODES)) != OK)
897 fprintf(stderr,
"Fatal error when reading task node data - bailing out..");
903 if ((read_taskconnections(gr, task_connections, NR_OF_TASKNODES)) != OK)
905 fprintf(stderr,
"Fatal error when reading taskconnections data - bailing out..");
917 if ((retval =
ALGOdfs(gr, &tasks)) != OK)
919 fprintf(stderr,
"\nFatal error when calling 'ALGOdfs()'(Return value: %d) - Bailing out..", retval);
924 printf(
"\n\nTopological Sort(DFS Analysis):\n-------------------------------");
928 printf(
"\nNode %c, color=%d", *(
char *)taskdata->
data, taskdata->color);
942 int menu_choice, retval;
950 menu_choice =
menu(MAIN_MENU_ROW, 0, 3);
955 if ((retval = basics()) != OK)
961 if ((retval = bfs()) != OK)
967 if ((retval = dfs()) != OK)