static int dfs_main(Graph * graph, AdjList * adjlist, List * ordered) { AdjList *clr_adjlist; DfsVertex *clr_vertex, *adj_vertex; ListElmt *member; /***************************************************************************** * Color the vertex gray and traverse its adjacency list. * *****************************************************************************/ ((DfsVertex *) adjlist->vertex)->color = gray; for (member = list_head(&adjlist->adjacent); member != NULL; member = list_next(member)) { /************************************************************************** * Determine the color of the next adjacent vertex. * **************************************************************************/ adj_vertex = list_data(member); if (graph_adjlist(graph, adj_vertex, &clr_adjlist) != 0) return -1; clr_vertex = clr_adjlist->vertex; /************************************************************************** * Move one vertex deeper when the next adjacent vertex is white. * **************************************************************************/ if (clr_vertex->color == white) { if (dfs_main(graph, clr_adjlist, ordered) != 0) return -1; } } /***************************************************************************** * Color the current vertex black and make it first in the list. * *****************************************************************************/ ((DfsVertex *) adjlist->vertex)->color = black; if (list_ins_next(ordered, NULL, (DfsVertex *) adjlist->vertex) != 0) return -1; return 0; }
int bfs(Graph *graph, BfsVertex *start, List *hops) { Queue queue; AdjList *adjlist, *clr_adjlist; BfsVertex *clr_vertex, *adj_vertex; ListElmt *element, *member; /***************************************************************************** * * * Initialize all of the vertices in the graph. * * * *****************************************************************************/ for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { clr_vertex = ((AdjList *)list_data(element))->vertex; if (graph->match(clr_vertex, start)) { /*********************************************************************** * * * Initialize the start vertex. * * * ***********************************************************************/ clr_vertex->color = gray; clr_vertex->hops = 0; } else { /*********************************************************************** * * * Initialize vertices other than the start vertex. * * * ***********************************************************************/ clr_vertex->color = white; clr_vertex->hops = -1; } } /***************************************************************************** * * * Initialize the queue with the adjacency list of the start vertex. * * * *****************************************************************************/ queue_init(&queue, NULL); if (graph_adjlist(graph, start, &clr_adjlist) != 0) { queue_destroy(&queue); return -1; } if (queue_enqueue(&queue, clr_adjlist) != 0) { queue_destroy(&queue); return -1; } /***************************************************************************** * * * Perform breadth-first search. * * * *****************************************************************************/ while (queue_size(&queue) > 0) { adjlist = queue_peek(&queue); /************************************************************************** * * * Traverse each vertex in the current adjacency list. * * * **************************************************************************/ for (member = list_head(&adjlist->adjacent); member != NULL; member = list_next(member)) { adj_vertex = list_data(member); /*********************************************************************** * * * Determine the color of the next adjacent vertex. * * * ***********************************************************************/ if (graph_adjlist(graph, adj_vertex, &clr_adjlist) != 0) { queue_destroy(&queue); return -1; } clr_vertex = clr_adjlist->vertex; /*********************************************************************** * * * Color each white vertex gray and enqueue its adjacency list. * * * ***********************************************************************/ if (clr_vertex->color == white) { clr_vertex->color = gray; clr_vertex->hops = ((BfsVertex *)adjlist->vertex)->hops + 1; if (queue_enqueue(&queue, clr_adjlist) != 0) { queue_destroy(&queue); return -1; } } } /************************************************************************** * * * Dequeue the current adjacency list and color its vertex black. * * * **************************************************************************/ if (queue_dequeue(&queue, (void **)&adjlist) == 0) { ((BfsVertex *)adjlist->vertex)->color = black; } else { queue_destroy(&queue); return -1; } } queue_destroy(&queue); /***************************************************************************** * * * Pass back the hop count for each vertex in a list. * * * *****************************************************************************/ list_init(hops, NULL); for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { /************************************************************************** * * * Skip vertices that were not visited (those with hop counts of -1). * * * **************************************************************************/ clr_vertex = ((AdjList *)list_data(element))->vertex; if (clr_vertex->hops != -1) { if (list_ins_next(hops, list_tail(hops), clr_vertex) != 0) { list_destroy(hops); return -1; } } } return 0; }
int main(int argc, char **argv) { Graph graph; AdjList *adjlist; ListElmt *element; char *data, data1[STRSIZ], *data2; int retval, size, i; /***************************************************************************** * * * Initialize the graph. * * * *****************************************************************************/ graph_init(&graph, match_str, free); /***************************************************************************** * * * Perform some graph operations. * * * *****************************************************************************/ if ((data = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data, "a"); fprintf(stdout, "Inserting vertex %s\n", data); if (graph_ins_vertex(&graph, data) != 0) return 1; if ((data = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data, "b"); fprintf(stdout, "Inserting vertex %s\n", data); if (graph_ins_vertex(&graph, data) != 0) return 1; if ((data = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data, "c"); fprintf(stdout, "Inserting vertex %s\n", data); if (graph_ins_vertex(&graph, data) != 0) return 1; if ((data = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data, "d"); fprintf(stdout, "Inserting vertex %s\n", data); if (graph_ins_vertex(&graph, data) != 0) return 1; if ((data = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data, "e"); fprintf(stdout, "Inserting vertex %s\n", data); if (graph_ins_vertex(&graph, data) != 0) return 1; print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "a"); strcpy(data2, "b"); fprintf(stdout, "Inserting edge %s to %s\n", data1, data2); if (graph_ins_edge(&graph, data1, data2) != 0) return 1; print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "a"); strcpy(data2, "c"); fprintf(stdout, "Inserting edge %s to %s\n", data1, data2); if (graph_ins_edge(&graph, data1, data2) != 0) return 1; print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "b"); strcpy(data2, "c"); fprintf(stdout, "Inserting edge %s to %s\n", data1, data2); if (graph_ins_edge(&graph, data1, data2) != 0) return 1; print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "b"); strcpy(data2, "d"); fprintf(stdout, "Inserting edge %s to %s\n", data1, data2); if (graph_ins_edge(&graph, data1, data2) != 0) return 1; print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "c"); strcpy(data2, "b"); fprintf(stdout, "Inserting edge %s to %s\n", data1, data2); if (graph_ins_edge(&graph, data1, data2) != 0) return 1; print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "c"); strcpy(data2, "c"); fprintf(stdout, "Inserting edge %s to %s\n", data1, data2); if (graph_ins_edge(&graph, data1, data2) != 0) return 1; print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "c"); strcpy(data2, "d"); fprintf(stdout, "Inserting edge %s to %s\n", data1, data2); if (graph_ins_edge(&graph, data1, data2) != 0) return 1; print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "d"); strcpy(data2, "a"); fprintf(stdout, "Inserting edge %s to %s\n", data1, data2); if (graph_ins_edge(&graph, data1, data2) != 0) return 1; print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "e"); strcpy(data2, "c"); fprintf(stdout, "Inserting edge %s to %s\n", data1, data2); if (graph_ins_edge(&graph, data1, data2) != 0) return 1; print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "e"); strcpy(data2, "d"); fprintf(stdout, "Inserting edge %s to %s\n", data1, data2); if (graph_ins_edge(&graph, data1, data2) != 0) return 1; print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "a"); strcpy(data2, "c"); data = data2; fprintf(stdout, "Removing edge %s to %s\n", data1, data2); if (graph_rem_edge(&graph, data1, (void **)&data) != 0) return 1; free(data); print_graph(&graph); strcpy(data1, "c"); strcpy(data2, "c"); data = data2; fprintf(stdout, "Removing edge %s to %s\n", data1, data2); if (graph_rem_edge(&graph, data1, (void **)&data) != 0) return 1; free(data); print_graph(&graph); strcpy(data1, "e"); strcpy(data2, "c"); data = data2; fprintf(stdout, "Removing edge %s to %s\n", data1, data2); if (graph_rem_edge(&graph, data1, (void **)&data) != 0) return 1; free(data); print_graph(&graph); strcpy(data1, "a"); strcpy(data2, "b"); data = data2; fprintf(stdout, "Removing edge %s to %s\n", data1, data2); if (graph_rem_edge(&graph, data1, (void **)&data) != 0) return 1; free(data); print_graph(&graph); strcpy(data1, "d"); strcpy(data2, "a"); data = data2; fprintf(stdout, "Removing edge %s to %s\n", data1, data2); if (graph_rem_edge(&graph, data1, (void **)&data) != 0) return 1; free(data); print_graph(&graph); free(data2); strcpy(data1, "a"); data = data1; fprintf(stdout, "Removing vertex %s\n", data1); if (graph_rem_vertex(&graph, (void **)&data) != 0) return 1; free(data); print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "f"); strcpy(data2, "a"); retval = graph_ins_edge(&graph, data1, data2); fprintf(stdout,"Inserting an invalid edge from %s to %s...Value=%d (-1=OK)\n", data1, data2, retval); if (retval != 0) free(data2); print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "c"); strcpy(data2, "b"); retval = graph_ins_edge(&graph, data1, data2); fprintf(stdout,"Inserting an existing edge from %s to %s...Value=%d (1=OK)\n", data1, data2, retval); if (retval != 0) free(data2); print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "f"); strcpy(data2, "a"); data = data2; retval = graph_rem_edge(&graph, data1, (void **)&data); fprintf(stdout, "Removing an invalid edge from %s to %s...Value=%d (-1=OK)\n", data1, data2, retval); if (retval == 0) free(data); free(data2); print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "c"); strcpy(data2, "e"); data = data2; retval = graph_rem_edge(&graph, data1, (void **)&data); fprintf(stdout, "Removing an invalid edge from %s to %s...Value=%d (-1=OK)\n", data1, data2, retval); if (retval == 0) free(data); free(data2); print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data2, "c"); retval = graph_ins_vertex(&graph, data2); fprintf(stdout, "Inserting an existing vertex %s...Value=%d (1=OK)\n", data1, retval); if (retval != 0) free(data2); print_graph(&graph); if ((data2 = (char *)malloc(STRSIZ)) == NULL) return 1; strcpy(data1, "b"); strcpy(data2, "d"); retval = graph_is_adjacent(&graph, data1, data2); fprintf(stdout, "Testing graph_is_adjacent (%s, %s)...Value=%d (1=OK)\n", data1, data2, retval); strcpy(data1, "a"); strcpy(data2, "e"); retval = graph_is_adjacent(&graph, data1, data2); fprintf(stdout, "Testing graph_is_adjacent (%s, %s)...Value=%d (0=OK)\n", data1, data2, retval); strcpy(data1, "e"); strcpy(data2, "d"); retval = graph_is_adjacent(&graph, data1, data2); fprintf(stdout, "Testing graph_is_adjacent (%s, %s)...Value=%d (1=OK)\n", data1, data2, retval); strcpy(data1, "c"); strcpy(data2, "a"); retval = graph_is_adjacent(&graph, data1, data2); fprintf(stdout, "Testing graph_is_adjacent (%s, %s)...Value=%d (0=OK)\n", data1, data2, retval); free(data2); strcpy(data1, "c"); if (graph_adjlist(&graph, data1, &adjlist) != 0) return 1; fprintf(stdout, "Vertices adjacent to %s: ", data1); i = 0; size = set_size(&adjlist->adjacent); element = list_head(&adjlist->adjacent); while (i < size) { i++; if (i > 1) fprintf(stdout, ", "); fprintf(stdout, "%s", (char *)list_data(element)); element = list_next(element); } fprintf(stdout, "\n"); /***************************************************************************** * * * Destroy the graph. * * * *****************************************************************************/ fprintf(stdout, "Destroying the graph\n"); graph_destroy(&graph); return 0; }