-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
140 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#include <stdlib.h> | ||
|
||
#include "dfs.h" | ||
#include "graph.h" | ||
#include "../ch5/list.h" | ||
|
||
|
||
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 color of 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 list */ | ||
((DfsVertex *) adjlist->vertex)->color = black; | ||
if (list_ins_next(ordered, NULL, (DfsVertex *) adjlist->vertex) != 0) | ||
return -1; | ||
|
||
return 0; | ||
} | ||
|
||
|
||
int dfs(Graph *graph, List *ordered) { | ||
DfsVertex *vertex; | ||
ListElmt *element; | ||
|
||
/* Initialize all vertices in graph */ | ||
for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { | ||
vertex = ((AdjList *) list_data(element))->vertex; | ||
vertex->color = white; | ||
} | ||
|
||
/* Perform depth-first search */ | ||
list_init(ordered, NULL); | ||
for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { | ||
/* Ensure that every component of unconnected graphs is searched */ | ||
vertex = ((AdjList *) list_data(element))->vertex; | ||
if (vertex->color == white) { | ||
if (dfs_main(graph, (AdjList *) list_data(element), ordered) != 0) { | ||
list_destroy(ordered); | ||
return -1; | ||
} | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#ifndef DFS_H | ||
#define DFS_H | ||
|
||
#include "graph.h" | ||
#include "../ch5/list.h" | ||
|
||
|
||
/* Define a structure for vertices in a depth-first search */ | ||
typedef struct DfsVertex_ { | ||
void *data; | ||
VertexColor color; | ||
} DfsVertex; | ||
|
||
|
||
int dfs(Graph *graph, List *ordered); | ||
|
||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#include <stdio.h> | ||
|
||
#include "dfs.h" | ||
|
||
|
||
int intcmp(int x, int y) { | ||
if (x == y) | ||
return 1; | ||
else | ||
return 0; | ||
} | ||
|
||
|
||
int main() { | ||
Graph graph; | ||
DfsVertex v1, v2, v3, v4, v5, v6, *dfs_vertex; | ||
List ordered; | ||
ListElmt *element; | ||
|
||
int v1data = 3; | ||
int v2data = 5; | ||
int v3data = 4; | ||
int v4data = 1; | ||
int v5data = 7; | ||
int v6data = 8; | ||
|
||
v1.data = &v1data; | ||
v2.data = &v2data; | ||
v3.data = &v3data; | ||
v4.data = &v4data; | ||
v5.data = &v5data; | ||
v6.data = &v6data; | ||
|
||
graph_init(&graph, (int (*)(const void *, const void *)) intcmp, NULL); | ||
graph_ins_vertex(&graph, &v1); | ||
graph_ins_vertex(&graph, &v2); | ||
graph_ins_vertex(&graph, &v3); | ||
graph_ins_vertex(&graph, &v4); | ||
graph_ins_vertex(&graph, &v5); | ||
graph_ins_vertex(&graph, &v6); | ||
graph_ins_edge(&graph, &v1, &v2); | ||
graph_ins_edge(&graph, &v1, &v3); | ||
graph_ins_edge(&graph, &v1, &v4); | ||
graph_ins_edge(&graph, &v3, &v4); | ||
graph_ins_edge(&graph, &v4, &v5); | ||
graph_ins_edge(&graph, &v5, &v6); | ||
|
||
if (dfs(&graph, &ordered) != 0) | ||
return -1; | ||
|
||
printf("Topological ordering of graph with depth-first search:\n"); | ||
for (element = list_head(&ordered); element != NULL; element = list_next(element)) { | ||
dfs_vertex = list_data(element); | ||
printf("%d\n", *((int *) dfs_vertex->data)); | ||
} | ||
|
||
return 0; | ||
} | ||
|