The LevAWC Project
 All Data Structures Files Functions Variables Typedefs Enumerations Macros Pages
demo11.c
1 /*
2  * _____
3  * ANSI / ___/
4  * / /__
5  * \___/
6  *
7  * Filename: demo11.c
8  * Author : Dan Levin
9  * Date : Wed Mar 11 09:14:04 2015
10  * Version : 0.51
11  * ---
12  * Description: Basic usage of Graph ADT
13  *
14  * Revision history: (this is where you document the diffs between versions...)
15  * Date Revision
16  * 150318 This source ready for version 0.51
17  */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 
22 #include "slist.h"
23 #include "graph.h"
24 #include "algo.h"
25 #include "utils.h"
26 
27 /* --- MACRO DEFINITIONS --- */
28 #define STRSIZ BUFSIZ/128
29 #define MESSIZ BUFSIZ/4
30 
31 #define ERR_DUPL 1
32 #define ERR_VTX_OR_EDGE_MISSING -2
33 #define ERR_VTX_NOT_ISOL -3
34 #define ERR_FATAL -1
35 
36 #ifndef OK
37 #define OK 0
38 #endif
39 
40 #ifndef TRUE
41 #define TRUE 1
42 #endif
43 
44 #ifndef FALSE
45 #define FALSE 0
46 #endif
47 
48 #define NR_OF_TASKNODES 9
49 #define NR_OF_NETNODES 6
50 
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"
52 
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 "
54 
55 /* --- GLOBAL VARIABLES --- */
56 /* Error indexes for messages */
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"};
63 /* Bfs Graph Data */
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}};
68 
69 /* Dfs Graph Data */
70 char task_nodes[NR_OF_TASKNODES] = {'a', 'b', 'c',
71  'd', 'e', 'f',
72  'g', 'h', 'i'};
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}};
77 
78 /* --- FUNCTION-DECLARATIONS --- */
79 /* Basic Usage Functions */
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);
89 
90 /* Bfs Functions */
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);
97 
98 /* Dfs Functions */
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);
105 /* --- END-FUNCTION-DECLARATIONS --- */
106 
107 /* --- FUNCTION DEFINITIONS --- */
108 /* --- Function: void prt_bas_vtx(const void *data) --- */
109 void prt_bas_vtx(const void *data)
110 {
111  printf("%s", (char *)data);
112 }
113 
114 /* --- Function: void prt_bas_edge(const void *data) --- */
115 void prt_bas_edge(const void *data)
116 {
117  printf("%s ", (char *)data);
118 }
119 /* --- Function: bas_match(const void *str1, const void *str2) --- */
120 static int bas_match(const void *str1, const void *str2)
121 {
122  return !strcmp((const char *)str1, (const char *)str2); /* Determine whether two strings match */
123 }
124 
125 /* --- Function: void print_info(Graph gr, void (*vtxprt)(const void *data), void (*edgprt)(const void *data)) --- */
126 void print_info(Graph gr, void (*vtxprt)(const void *data), void (*edgprt)(const void *data))
127 {
128  my_clearscrn();
129  printf("--- BASIC GRAPH OPERATIONS ---\n");
130  GRAPHprint(gr, vtxprt, edgprt);
131  printf("\n\nNr of vertices/edges: %d/%d ", GRAPHvcount(gr), GRAPHecount(gr));
132 }
133 
134 /* --- Function: void print_errmess(int errcode) --- */
135 void print_errmess(int errcode)
136 {
137  switch (errcode)
138  {
139  case ERR_DUPL:
140  prompt_and_pause(err_mess[err_dupl]);
141  break;
142  case ERR_VTX_OR_EDGE_MISSING:
143  prompt_and_pause(err_mess[err_vtx_or_edge_missing]);
144  break;
145  case ERR_VTX_NOT_ISOL:
146  prompt_and_pause(err_mess[err_vtx_not_isol]);
147  break;
148  case ERR_FATAL:
149  prompt_and_pause(err_mess[err_fatal]);
150  break;
151  default:
152  prompt_and_pause(err_mess[no_err]);
153  break;
154  }
155 }
156 
157 /* --- Function: void print_testmess(int testcode) --- */
158 void print_testmess(int testcode)
159 {
160  if (testcode)
161  printf("\n\nVertices ARE adjacent..");
162  else
163  printf("\n\nVertices are NOT adjacent..");
164 }
165 
166 /* --- Function: void basics(void) --- */
167 int basics(void)
168 {
169  Graph gr;
170  VertexNode vnode;
171  EdgeNode enode;
172  char data[STRSIZ], *pdata1, *pdata2;
173  int retval;
174  char mess[MESSIZ];
175 
176  /* Initialize the graph. */
177  gr = GRAPHinit(bas_match, free);
178  my_clearscrn();
179  printf("--- BASIC GRAPH USAGE ---\n\nGraph created.. - let's do some basic graph editing..");
180  /* --- Perform some graph operations --- */
181  /* --- Start with inserting some vertices.. --- */
182 
183  /* Insert first vertex.. */
184  if ((pdata1 = (char *)malloc(STRSIZ)) == NULL)
185  return 1;
186  strcpy(pdata1, "a");
187  sprintf(mess, "\n\nInsert first vertex: %s", pdata1);
188  prompt_and_pause(mess);
189  if (GRAPHinsvertex(gr, pdata1) != 0) /* Do the insertion.. */
190  return 1;
191  /* Print the result.. */
192  print_info(gr, prt_bas_vtx, prt_bas_edge);
193 
194  /* Insert next vertex.. */
195  if ((pdata1 = (char *)malloc(STRSIZ)) == NULL)
196  return 1;
197  strcpy(pdata1, "b");
198  sprintf(mess, "\n\nInsert vertex: %s", pdata1);
199  prompt_and_pause(mess);
200  if (GRAPHinsvertex(gr, pdata1) != 0) /* Do the insertion.. */
201  return 1;
202  /* Print the result.. */
203  print_info(gr, prt_bas_vtx, prt_bas_edge);
204 
205  /* Insert next vertex.. */
206  if ((pdata1 = (char *)malloc(STRSIZ)) == NULL)
207  return 1;
208  strcpy(pdata1, "c");
209  sprintf(mess, "\n\nInsert vertex: %s", pdata1);
210  prompt_and_pause(mess);
211  if (GRAPHinsvertex(gr, pdata1) != 0) /* Do the insertion.. */
212  return 1;
213  /* Print the result.. */
214  print_info(gr, prt_bas_vtx, prt_bas_edge);
215 
216  /* Insert next vertex.. */
217  if ((pdata1 = (char *)malloc(STRSIZ)) == NULL)
218  return 1;
219  strcpy(pdata1, "d");
220  sprintf(mess, "\n\nInsert vertex: %s", pdata1);
221  prompt_and_pause(mess);
222  if (GRAPHinsvertex(gr, pdata1) != 0) /* Do the insertion.. */
223  return 1;
224  /* Print the result.. */
225  print_info(gr, prt_bas_vtx, prt_bas_edge);
226 
227  /* Insert next vertex.. */
228  if ((pdata1 = (char *)malloc(STRSIZ)) == NULL)
229  return 1;
230  strcpy(pdata1, "e");
231  sprintf(mess, "\n\nInsert vertex: %s", pdata1);
232  prompt_and_pause(mess);
233  if (GRAPHinsvertex(gr, pdata1) != 0) /* Do the insertion.. */
234  return 1;
235  /* Print the result.. */
236  print_info(gr, prt_bas_vtx, prt_bas_edge);
237 
238  prompt_and_pause("\n\nCheck out all vertex insertions above..");
239 
240  /* --- Now, let's insert some edges.. --- */
241  /* Insert first edge.. */
242  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
243  return 1;
244  strcpy(data, "a");
245  strcpy(pdata2, "b");
246  sprintf(mess, "\nNow - let's insert edge: %s --> %s", data, pdata2);
247  prompt_and_pause(mess);
248  if (GRAPHinsedge(gr, data, pdata2) != 0) /* Do the insertion.. */
249  return 1;
250  /* Print the result.. */
251  print_info(gr, prt_bas_vtx, prt_bas_edge);
252 
253  /* Insert next edge.. */
254  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
255  return 1;
256  strcpy(data, "a");
257  strcpy(pdata2, "c");
258  sprintf(mess, "\n\nInsert edge: %s --> %s", data, pdata2);
259  prompt_and_pause(mess);
260  if (GRAPHinsedge(gr, data, pdata2) != 0)
261  return 1;
262  /* Print the result.. */
263  print_info(gr, prt_bas_vtx, prt_bas_edge);
264 
265  /* Insert next edge.. */
266  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
267  return 1;
268  strcpy(data, "b");
269  strcpy(pdata2, "c");
270  sprintf(mess, "\n\nInsert edge: %s --> %s", data, pdata2);
271  prompt_and_pause(mess);
272  if (GRAPHinsedge(gr, data, pdata2) != 0) /* Do the insertion.. */
273  return 1;
274  /* Print the result.. */
275  print_info(gr, prt_bas_vtx, prt_bas_edge);
276 
277  /* Insert next edge.. */
278  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
279  return 1;
280  strcpy(data, "b");
281  strcpy(pdata2, "d");
282  sprintf(mess, "\n\nInsert edge: %s --> %s", data, pdata2);
283  prompt_and_pause(mess);
284  if (GRAPHinsedge(gr, data, pdata2) != 0) /* Do the insertion.. */
285  return 1;
286  /* Print the result.. */
287  print_info(gr, prt_bas_vtx, prt_bas_edge);
288 
289  /* Insert next edge.. */
290  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
291  return 1;
292  strcpy(data, "c");
293  strcpy(pdata2, "b");
294  sprintf(mess, "\n\nInsert edge: %s --> %s", data, pdata2);
295  prompt_and_pause(mess);
296  if (GRAPHinsedge(gr, data, pdata2) != 0) /* Do the insertion.. */
297  return 1;
298  /* Print the result.. */
299  print_info(gr, prt_bas_vtx, prt_bas_edge);
300 
301  /* Insert next edge.. */
302  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
303  return 1;
304  strcpy(data, "c");
305  strcpy(pdata2, "c");
306  sprintf(mess, "\n\nInsert edge: %s --> %s", data, pdata2);
307  prompt_and_pause(mess);
308  if (GRAPHinsedge(gr, data, pdata2) != 0)/* Do the insertion.. */
309  return 1;
310  /* Print the result.. */
311  print_info(gr, prt_bas_vtx, prt_bas_edge);
312 
313  /* Insert next edge.. */
314  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
315  return 1;
316  strcpy(data, "c");
317  strcpy(pdata2, "d");
318  sprintf(mess, "\n\nInsert edge: %s --> %s", data, pdata2);
319  prompt_and_pause(mess);
320  if (GRAPHinsedge(gr, data, pdata2) != 0) /* Do the insertion.. */
321  return 1;
322  /* Print the result.. */
323  print_info(gr, prt_bas_vtx, prt_bas_edge);
324 
325  /* Insert next edge.. */
326  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
327  return 1;
328  strcpy(data, "d");
329  strcpy(pdata2, "a");
330  sprintf(mess, "\n\nInsert edge: %s --> %s", data, pdata2);
331  prompt_and_pause(mess);
332  if (GRAPHinsedge(gr, data, pdata2) != 0) /* Do the insertion.. */
333  return 1;
334  /* Print the result.. */
335  print_info(gr, prt_bas_vtx, prt_bas_edge);
336 
337  /* Insert next edge.. */
338  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
339  return 1;
340  strcpy(data, "e");
341  strcpy(pdata2, "c");
342  sprintf(mess, "\n\nInsert edge: %s --> %s", data, pdata2);
343  prompt_and_pause(mess);
344  if (GRAPHinsedge(gr, data, pdata2) != 0) /* Do the insertion.. */
345  return 1;
346  /* Print the result.. */
347  print_info(gr, prt_bas_vtx, prt_bas_edge);
348 
349  /* Insert next edge.. */
350  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
351  return 1;
352  strcpy(data, "e");
353  strcpy(pdata2, "d");
354  sprintf(mess, "\n\nInsert edge: %s --> %s", data, pdata2);
355  prompt_and_pause(mess);
356  if (GRAPHinsedge(gr, data, pdata2) != 0) /* Do the insertion.. */
357  return 1;
358  /* Print the result.. */
359  print_info(gr, prt_bas_vtx, prt_bas_edge);
360 
361  /* Now, let's remove some edges.. */
362  /* Remove first edge.. */
363  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
364  return 1;
365  strcpy(data, "a");
366  strcpy(pdata2, "c");
367  pdata1 = pdata2;
368  sprintf(mess, "\n\nRemove edge %s --> %s", data, pdata2);
369  prompt_and_pause(mess);
370  if (GRAPHremedge(gr, data, (void **)&pdata1) != 0) /* Do the removal.. */
371  {
372  free(pdata2);
373  return 1;
374  }
375  free(pdata1); /* Deallocate mem. held by removed edge.. */
376  /* Print the result.. */
377  print_info(gr, prt_bas_vtx, prt_bas_edge);
378 
379  /* Remove next edge.. */
380  strcpy(data, "c");
381  strcpy(pdata2, "c");
382  pdata1 = pdata2;
383  sprintf(mess, "\n\nRemove edge %s --> %s", data, pdata2);
384  prompt_and_pause(mess);
385  if (GRAPHremedge(gr, data, (void **)&pdata1) != 0) /* Do the removal.. */
386  {
387  free(pdata2);
388  return 1;
389  }
390  free(pdata1); /* Deallocate mem. held by removed edge.. */
391  /* Print the result.. */
392  print_info(gr, prt_bas_vtx, prt_bas_edge);
393 
394  /* Remove next edge.. */
395  strcpy(data, "e");
396  strcpy(pdata2, "c");
397  pdata1 = pdata2;
398  sprintf(mess, "\n\nRemove edge %s --> %s", data, pdata2);
399  prompt_and_pause(mess);
400  if (GRAPHremedge(gr, data, (void **)&pdata1) != 0) /* Do the removal.. */
401  {
402  free(pdata2);
403  return 1;
404  }
405  free(pdata1); /* Deallocate mem. held by removed edge.. */
406  /* Print the result.. */
407  print_info(gr, prt_bas_vtx, prt_bas_edge);
408 
409  /* Remove next edge.. */
410  strcpy(data, "a");
411  strcpy(pdata2, "b");
412  pdata1 = pdata2;
413  sprintf(mess, "\n\nRemove edge %s --> %s", data, pdata2);
414  prompt_and_pause(mess);
415  if (GRAPHremedge(gr, data, (void **)&pdata1) != 0) /* Do the removal.. */
416  {
417  free(pdata2);
418  return 1;
419  }
420  free(pdata1); /* Deallocate mem. held by removed edge.. */
421  /* Print the result.. */
422  print_info(gr, prt_bas_vtx, prt_bas_edge);
423 
424  /* Remove next edge.. */
425  strcpy(data, "d");
426  strcpy(pdata2, "a");
427  pdata1 = pdata2;
428  sprintf(mess, "\n\nRemove edge %s --> %s", data, pdata2);
429  prompt_and_pause(mess);
430  if (GRAPHremedge(gr, data, (void **)&pdata1) != 0) /* Do the removal.. */
431  {
432  free(pdata2);
433  return 1;
434  }
435  free(pdata1); /* Deallocate mem. held by removed edge.. */
436  free(pdata2); /* Deallocate mem. held by search key value(=a).. */
437  /* Print the result.. */
438  print_info(gr, prt_bas_vtx, prt_bas_edge);
439 
440  /* Now, lets remove a vertex.. */
441  strcpy(data, "a");
442  pdata1 = data;
443  sprintf(mess, "\n\nRemove vertex %s", data);
444  prompt_and_pause(mess);
445  if (GRAPHremvertex(gr, (void **)&pdata1) != 0) /* Do the removal.. */
446  return 1;
447  free(pdata1); /* Deallocate mem. held by removed vertex.. */
448  /* Print the result.. */
449  print_info(gr, prt_bas_vtx, prt_bas_edge);
450 
451  /* --- Do some invalid insertions/removals --- */
452  /* First invalid operation.. */
453  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
454  return 1;
455  strcpy(data, "f");
456  strcpy(pdata2, "a");
457  sprintf(mess,"\n\nNow - try to insert an invalid edge from %s --> %s", data, pdata2);
458  prompt_and_pause(mess);
459  retval = GRAPHinsedge(gr, data, pdata2); /* Do the insertion.. */
460  if (retval != 0)
461  free(pdata2); /* Deallocte mem. held by search key value(=a).. */
462  /* Print the result.. */
463  print_info(gr, prt_bas_vtx, prt_bas_edge);
464  print_errmess(retval);
465 
466  /* Next invalid operation.. */
467  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
468  return 1;
469  strcpy(data, "c");
470  strcpy(pdata2, "b");
471  sprintf(mess,"\nInsert an existing edge from %s --> %s", data, pdata2);
472  prompt_and_pause(mess);
473  retval = GRAPHinsedge(gr, data, pdata2); /* Do the insertion.. */
474  if (retval != 0)
475  free(pdata2); /* Deallocte mem. held by search key value(=b).. */
476  /* Print the result.. */
477  print_info(gr, prt_bas_vtx, prt_bas_edge);
478  print_errmess(retval);
479 
480  /* Next invalid operation.. */
481  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
482  return 1;
483  strcpy(data, "f");
484  strcpy(pdata2, "a");
485  pdata1 = pdata2;
486  retval = GRAPHremedge(gr, data, (void **)&pdata2); /* Do the removal.. */
487  sprintf(mess, "\nRemove an invalid edge from %s --> %s", data, pdata2);
488  prompt_and_pause(mess);
489  if (retval == 0)
490  {
491  free(pdata2); /* Deallocte mem. held by removed edge.. */
492  free(pdata1); /* Deallocte mem. held by search key value(=b).. */
493  return 1;
494  }
495  free(pdata2); /* Deallocte mem. held by search key value(=b).. */
496  /* Print the result.. */
497  print_info(gr, prt_bas_vtx, prt_bas_edge);
498  print_errmess(retval);
499 
500  /* Next invalid operation.. */
501  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
502  return 1;
503  strcpy(data, "c");
504  strcpy(pdata2, "e");
505  pdata1 = pdata2;
506  retval = GRAPHremedge(gr, data, (void **)&pdata2); /* Do the removal.. */
507  sprintf(mess, "\nRemoving an invalid edge from %s --> %s", data, pdata2);
508  prompt_and_pause(mess);
509  if (retval == 0)
510  {
511  free(pdata2); /* Deallocte mem. held by removed edge.. */
512  free(pdata1); /* Deallocte mem. held by search key value(=e).. */
513  return 1;
514  }
515  free(pdata2); /* Deallocte mem. held by search key value(=e).. */
516  /* Print the result.. */
517  print_info(gr, prt_bas_vtx, prt_bas_edge);
518  print_errmess(retval);
519 
520  /* Next invalid operation.. */
521  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
522  return 1;
523  strcpy(pdata2, "c");
524  retval = GRAPHinsvertex(gr, pdata2); /* Do the insertion.. */
525  sprintf(mess, "\nInsert an existing vertex %s", data);
526  prompt_and_pause(mess);
527  if (retval != 0) /* Insertion failed - which is the case here.. */
528  free(pdata2); /* Deallocte mem. held by search key value(=c).. */
529  /* Print the result.. */
530  print_info(gr, prt_bas_vtx, prt_bas_edge);
531  print_errmess(retval);
532 
533  /* Next invalid operation.. */
534  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
535  return 1;
536  strcpy(pdata2, "c");
537  pdata1 = pdata2;
538  retval = GRAPHremvertex(gr, (void **)&pdata2); /* Do the insertion.. */
539  sprintf(mess, "\nRemove an existing vertex %s", pdata1);
540  prompt_and_pause(mess);
541  if (retval == 0)
542  {
543  free(pdata2); /* Deallocte mem. held by removed vertex.. */
544  free(pdata1); /* Deallocte mem. held by search key value(=c).. */
545  return 1;
546  }
547  free(pdata2); /* Deallocte mem. held by search key value(=c).. */
548  /* Print the result.. */
549  print_info(gr, prt_bas_vtx, prt_bas_edge);
550  print_errmess(retval);
551 
552  /* Next invalid operation.. */
553  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
554  return 1;
555  strcpy(pdata2, "d");
556  pdata1 = pdata2;
557  retval = GRAPHremvertex(gr, (void **)&pdata2); /* Do the insertion.. */
558  sprintf(mess, "\nRemove an existing vertex %s", pdata1);
559  prompt_and_pause(mess);
560  if (retval == 0)
561  {
562  free(pdata2); /* Deallocte mem. held by removed vertex.. */
563  free(pdata1); /* Deallocte mem. held by search key value(=d).. */
564  return 1;
565  }
566  free(pdata2); /* Deallocte mem. held by search key value(=d).. */
567  /* Print the result.. */
568  print_info(gr, prt_bas_vtx, prt_bas_edge);
569  print_errmess(retval);
570 
571  /* --- Testing GRAPHis_adjacent() --- */
572  /* First test of GRAPHis_adjacent().. */
573  if ((pdata2 = (char *)malloc(STRSIZ)) == NULL)
574  return 1;
575  strcpy(data, "b");
576  strcpy(pdata2, "d");
577  retval = GRAPHis_adjacent(gr, data, pdata2); /* Do the test.. */
578  sprintf(mess, "\nTest if (%s, %s) are adjacent...", data, pdata2);
579  prompt_and_pause(mess);
580  /* Print the result.. */
581  print_info(gr, prt_bas_vtx, prt_bas_edge);
582  print_testmess(retval);
583 
584  /* Next test of GRAPHis_adjacent().. */
585  strcpy(data, "a");
586  strcpy(pdata2, "e");
587  retval = GRAPHis_adjacent(gr, data, pdata2); /* Do the test.. */
588  sprintf(mess, "\n\nTest if (%s, %s) are adjacent...", data, pdata2);
589  prompt_and_pause(mess);
590  /* Print the result.. */
591  print_info(gr, prt_bas_vtx, prt_bas_edge);
592  print_testmess(retval);
593 
594  /* Next test of GRAPHis_adjacent().. */
595  strcpy(data, "e");
596  strcpy(pdata2, "d");
597  retval = GRAPHis_adjacent(gr, data, pdata2); /* Do the test.. */
598  sprintf(mess, "\n\nTest if (%s, %s) are adjacent...", data, pdata2);
599  prompt_and_pause(mess);
600  /* Print the result.. */
601  print_info(gr, prt_bas_vtx, prt_bas_edge);
602  print_testmess(retval);
603 
604  /* Next test of GRAPHis_adjacent().. */
605  strcpy(data, "c");
606  strcpy(pdata2, "a");
607  retval = GRAPHis_adjacent(gr, data, pdata2); /* Do the test.. */
608  sprintf(mess, "\n\nTest if (%s, %s) are adjacent...", data, pdata2);
609  prompt_and_pause(mess);
610  /* Print the result.. */
611  print_info(gr, prt_bas_vtx, prt_bas_edge);
612  print_testmess(retval);
613 
614  /* Free temporary dyn. memory - no longer used.. */
615  free(pdata2);
616 
617  /* Print all adjacent vertices - to a certain vertex.. */
618  strcpy(data, "c");
619  sprintf(mess, "\n\nFinally - print vertices adjacent to %s: ", data);
620  prompt_and_pause(mess);
621 
622  vnode = GRAPHfindvertex(gr, data);
623  printf("\nVertices adjacent(=incident) from %s (%d pcs): ", data, GRAPHgetedgecount(vnode));
624 
625  for (enode = GRAPHgetedgehead(vnode); enode != NULL; enode = GRAPHgetedgenext(enode))
626  {
627  printf("%s ", (char *)GRAPHgetedgedata(enode));
628  }
629 
630  /* Destroy the graph. */
631  sprintf(mess, "\n\nTime to tidy up..");
632  prompt_and_pause(mess);
633 
634  GRAPHdestroy(gr);
635 
636  return OK;
637 }
638 
639 /* --- Function: void bfs_destroy(void *data) --- */
640 void bfs_destroy(void *data)
641 {
642  free(((BfsVertexdata)data)->data);
643  free((BfsVertexdata)data);
644 }
645 
646 /* --- Function: void prt_bfs_vtx(const void *data) --- */
647 void prt_bfs_vtx(const void *data)
648 {
649  printf("Node%02d", *(int *)((BfsVertexdata)data)->data);
650 }
651 
652 /* --- Function: void prt_bfs_edge(const void *data) --- */
653 void prt_bfs_edge(const void *data)
654 {
655  printf("Node%02d ", *(int *)((BfsVertexdata)data)->data);
656 }
657 
658 /* --- Function: int bfs_match(const void *k1, const void *k2) --- */
659 int bfs_match(const void *k1, const void *k2)
660 {
661  return *(int *)((BfsVertexdata)k1)->data == *(int *)((BfsVertexdata)k2)->data;
662 }
663 
664 /* --- Function: int read_netnodes(Graph gr, int *pnodes, int nr_of_nodes) --- */
665 int read_netnodes(Graph gr, int *pnodes, int nr_of_nodes)
666 {
667  int i, retval;
668  BfsVertexdata bfs;
669 
670  for (i = 0; i < nr_of_nodes; ++i)
671  {
672  bfs = (BfsVertexdata)malloc(sizeof(struct BfsVertexdata_));
673  MALCHK(bfs);
674 
675  bfs->data = (int *)malloc(sizeof(int));
676  MALCHK(bfs->data);
677 
678  /* Copy data to vertex.. */
679  *((int *)bfs->data) = *(pnodes+i);
680 
681  if ((retval = GRAPHinsvertex(gr, bfs)) != OK)
682  {
683  bfs_destroy(bfs);
684  return retval;
685  }
686  }
687 
688  /* Everything OK */
689  return OK;
690 }
691 
692 /* --- Function: int read_netconnections(Graph gr, int netconn[][NR_OF_NETNODES], int nr_of_nodes) --- */
693 int read_netconnections(Graph gr, int netconn[][NR_OF_NETNODES], int nr_of_nodes)
694 {
695  int i, j, tmp, retval;
696  struct BfsVertexdata_ bfstmp;
697  BfsVertexdata bfs;
698 
699  for (i = 0; i < nr_of_nodes; ++i)
700  {
701  for (j = 0; j < nr_of_nodes; ++j)
702  {
703  if (netconn[i][j] != 0)
704  {
705  bfs = (BfsVertexdata)malloc(sizeof(struct BfsVertexdata_));
706  MALCHK(bfs);
707 
708  bfs->data = (int *)malloc(sizeof(int));
709  MALCHK(bfs->data);
710 
711  *(int *)bfs->data = j+1;
712 
713  /* Temporary vertex (search) data.. */
714  tmp = i+1;
715  bfstmp.data = &tmp;
716 
717  if ((retval = GRAPHinsedge(gr, &bfstmp, bfs)) != OK)
718  {
719  bfs_destroy(bfs);
720  return retval;
721  }
722  }
723  }
724  }
725  /* Everything OK */
726  return OK;
727 }
728 
729 int bfs(void)
730 {
731  Graph gr;
732  Slist network;
733  struct BfsVertexdata_ bfstmp;
734  BfsVertexdata netdata;
735  int tmpid, retval;
736  SlistNode listnode;
737 
738  my_clearscrn();
739  printf("--- NETWORK HOPS/BFS DEMO ---");
740 
741  gr = GRAPHinit(bfs_match, bfs_destroy);
742 
743  /* Read net node(=vertex) data into graph.. */
744  if ((read_netnodes(gr, net_nodes, NR_OF_NETNODES)) != OK)
745  {
746  fprintf(stderr, "Fatal error when reading netnode data - bailing out..");
747  GRAPHdestroy(gr);
748  exit(-1);
749  }
750  /* Read net connection(=edge) data into graph.. */
751  if ((read_netconnections(gr, net_connections, NR_OF_NETNODES)) != OK)
752  {
753  fprintf(stderr, "Fatal error when reading netconnections data - bailing out..");
754  GRAPHdestroy(gr);
755  exit(-1);
756  }
757 
758  prompt_and_pause("\n\nGraph initialized and graph data read..");
759  printf("\nGRAPH:");
760 
761  /* Display graph.. */
762  GRAPHprint(gr, prt_bfs_vtx, prt_bfs_edge);
763  printf("\nNr of vertices/edges: %d/%d", GRAPHvcount(gr), GRAPHecount(gr));
764 
765  tmpid = read_int("\nEnter startnode id ", 1, 6);
766  bfstmp.data = &tmpid;
767 
768  if ((retval = ALGObfs(gr, &bfstmp, &network, bfs_match)) != OK)
769  {
770  fprintf(stderr, "\nFatal error when calling 'ALGObfs()'(Return value: %d) - Bailing out..", retval);
771  GRAPHdestroy(gr);
772  exit(-1);
773  }
774 
775  printf("\nNetwork Hops(BFS Analysis)\n--------------------------");
776  for (listnode = SLISThead(network); listnode != NULL; listnode = SLISTnext(listnode))
777  {
778  netdata = (BfsVertexdata)SLISTdata(listnode);
779  printf("\nNode%02d, color=%d, hops=%d", *(int *)netdata->data, netdata->color, netdata->hops);
780  }
781 
782  prompt_and_pause("\n\nTime to tidy up..");
783 
784  SLISTdestroy(network);
785  GRAPHdestroy(gr);
786 
787  return OK;
788 }
789 
790 /* --- Function: void dfs_destroy(void *data) --- */
791 void dfs_destroy(void *data)
792 {
793  free(((DfsVertexdata)data)->data);
794  free((DfsVertexdata)data);
795 }
796 
797 /* --- Function: void prt_dfs_vtx(const void *data) --- */
798 void prt_dfs_vtx(const void *data)
799 {
800  printf("%c", *(char *)((DfsVertexdata)data)->data);
801 }
802 
803 /* --- Function: void prt_dfs_edge(const void *data) --- */
804 void prt_dfs_edge(const void *data)
805 {
806  printf("%c ", *(char *)((DfsVertexdata)data)->data);
807 }
808 
809 /* --- Function: int dfs_match(const void *k1, const void *k2) --- */
810 int dfs_match(const void *k1, const void *k2)
811 {
812  return *(char *)((DfsVertexdata)k1)->data == *(char *)((DfsVertexdata)k2)->data;
813 }
814 
815 /* --- Function: int read_tasknodes(Graph gr, char *pnodes, int nr_of_nodes) --- */
816 int read_tasknodes(Graph gr, char *pnodes, int nr_of_nodes)
817 {
818  int i, retval;
819  DfsVertexdata dfs;
820 
821  for (i = 0; i < nr_of_nodes; ++i)
822  {
823  dfs = (DfsVertexdata)malloc(sizeof(struct DfsVertexdata_));
824  MALCHK(dfs);
825 
826  dfs->data = (char *)malloc(sizeof(char));
827  MALCHK(dfs->data);
828 
829  /* Copy data to vertex.. */
830  *((char *)dfs->data) = *(pnodes+i);
831  /* *pi = *(pnodes+i); */
832 
833  if ((retval = GRAPHinsvertex(gr, dfs)) != OK)
834  {
835  dfs_destroy(dfs);
836  return retval;
837  }
838  }
839 
840  /* Everything OK */
841  return OK;
842 }
843 
844 /* --- Function: int read_taskconnections(Graph gr, char taskconn[][NR_OF_TASKNODES], int nr_of_nodes) --- */
845 int read_taskconnections(Graph gr, char taskconn[][NR_OF_TASKNODES], int nr_of_nodes)
846 {
847  int i, j, tmp, retval;
848  struct DfsVertexdata_ dfstmp;
849  DfsVertexdata dfs;
850 
851  for (i = 0; i < nr_of_nodes; ++i)
852  {
853  for (j = 0; j < nr_of_nodes; ++j)
854  {
855  if (taskconn[i][j] != 0)
856  {
857  dfs = (DfsVertexdata)malloc(sizeof(struct DfsVertexdata_));
858  MALCHK(dfs);
859 
860  dfs->data = (char *)malloc(sizeof(char));
861  MALCHK(dfs->data);
862 
863  *(char *)dfs->data = 'a'+j;
864 
865  /* Temporary vertex (search) data.. */
866  tmp = 'a'+i;
867  dfstmp.data = &tmp;
868 
869  if ((retval = GRAPHinsedge(gr, &dfstmp, dfs)) != OK)
870  {
871  dfs_destroy(dfs);
872  return retval;
873  }
874  }
875  }
876  }
877  /* Everything OK */
878  return OK;
879 }
880 
881 int dfs(void)
882 {
883  Graph gr;
884  Slist tasks;
885  DfsVertexdata taskdata;
886  int retval;
887  SlistNode listnode;
888 
889  my_clearscrn();
890  printf("--- TOPOLOGICAL SORTING/DFS DEMO ---");
891 
892  gr = GRAPHinit(dfs_match, dfs_destroy);
893 
894  /* Read task node(=vertex) data into graph.. */
895  if ((read_tasknodes(gr, task_nodes, NR_OF_TASKNODES)) != OK)
896  {
897  fprintf(stderr, "Fatal error when reading task node data - bailing out..");
898  GRAPHdestroy(gr);
899  exit(-1);
900  }
901 
902  /* Read task connection(=edge) data into graph.. */
903  if ((read_taskconnections(gr, task_connections, NR_OF_TASKNODES)) != OK)
904  {
905  fprintf(stderr, "Fatal error when reading taskconnections data - bailing out..");
906  GRAPHdestroy(gr);
907  exit(-1);
908  }
909 
910  prompt_and_pause("\n\nGraph created and graph data read..");
911  printf("\nGRAPH:");
912 
913  /* Display graph.. */
914  GRAPHprint(gr, prt_dfs_vtx, prt_dfs_edge);
915  printf("\nNr of vertices/edges: %d/%d", GRAPHvcount(gr), GRAPHecount(gr));
916 
917  if ((retval = ALGOdfs(gr, &tasks)) != OK)
918  {
919  fprintf(stderr, "\nFatal error when calling 'ALGOdfs()'(Return value: %d) - Bailing out..", retval);
920  GRAPHdestroy(gr);
921  exit(-1);
922  }
923 
924  printf("\n\nTopological Sort(DFS Analysis):\n-------------------------------");
925  for (listnode = SLISThead(tasks); listnode != NULL; listnode = SLISTnext(listnode))
926  {
927  taskdata = (DfsVertexdata)SLISTdata(listnode);
928  printf("\nNode %c, color=%d", *(char *)taskdata->data, taskdata->color);
929  }
930 
931  prompt_and_pause("\n\nTime to tidy up..");
932 
933  SLISTdestroy(tasks);
934  GRAPHdestroy(gr);
935 
936  return OK;
937 }
938 
939 int main(void)
940 {
941  /* Declare YOUR variables here ! */
942  int menu_choice, retval;
943 
944  my_clearscrn();
945  prompt_and_pause(INITIAL_INFO);
946 
947  /* Enter menu loop.. */
948  do
949  {
950  menu_choice = menu(MAIN_MENU_ROW, 0, 3);
951 
952  switch (menu_choice)
953  {
954  case 1:
955  if ((retval = basics()) != OK)
956  {
957  exit(EXIT_FAILURE);
958  }
959  break;
960  case 2:
961  if ((retval = bfs()) != OK)
962  {
963  exit(EXIT_FAILURE);
964  }
965  break;
966  case 3:
967  if ((retval = dfs()) != OK)
968  {
969  exit(EXIT_FAILURE);
970  }
971  break;
972  default:
973  prompt_and_pause("\nThat's all folks - Bye..!");
974  break;
975  }
976  }
977  while (menu_choice);
978 
979  return 0;
980 }