From 3a27588d6f9a5cd69f844398b1fda20f0021515c Mon Sep 17 00:00:00 2001 From: zenon Date: Mon, 21 May 2018 18:08:04 +0200 Subject: [PATCH] Graph implementation and correct parsing of edges --- generator.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 1 deletion(-) diff --git a/generator.c b/generator.c index 83a9cd6..0b2df47 100644 --- a/generator.c +++ b/generator.c @@ -6,11 +6,26 @@ */ #include "common.h" +#include static const char *pname; struct sigaction sa; +struct AdjListNode { + int dest; + struct AdjListNode *next; +}; + +struct AdjList { + struct AdjListNode *head; +}; + +struct Graph { + int V; + struct AdjList *array; +}; + static volatile sig_atomic_t quit = 0; static void sig_handler(int signum) @@ -27,6 +42,128 @@ void usage(void) exit(EXIT_FAILURE); } +struct AdjListNode *newAdjListNode(int dest) +{ + struct AdjListNode *newNode = malloc(sizeof(struct AdjListNode)); + newNode->dest = dest; + newNode->next = NULL; + return newNode; +} + +struct Graph *createGraph(int V) +{ + struct Graph *graph = malloc(sizeof(struct Graph)); + graph->V = V; + + graph->array = malloc(V * sizeof(struct AdjList)); + + for (int i = 0; i < V; i++) + graph->array[i].head = NULL; + + return graph; +} + +void addEdge(struct Graph *graph, int src, int dest) +{ + struct AdjListNode *newNode = newAdjListNode(dest); + newNode->next = graph->array[src].head; + graph->array[src].head = newNode; +} + +int strToInt(char *str) +{ + char *endptr; + long val; + + val = strtol(str, &endptr, 10); + if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || + (errno != 0)) { + perror(pname); + return -2; + } + if (val < INT_MIN || val > INT_MAX) { + fprintf(stderr, "[%s] Please choose a smaller node: ", pname); + return -1; + } + + return (int) val; +} + +struct Graph *parse(int argc, char *argv[]) +{ + char *edge; + char *token; + char *str; + int V = 0; + int src; + int dest; + int edges_counter = 0; + int edges[(argc - 1) * 2]; + + for (int i = 1; i < argc; i++) { + edge = argv[i]; + str = strdup(edge); + int count = 0; + while ((token = strsep(&str, "-"))) { + if (count == 0) { + src = strToInt(token); + edges[edges_counter] = src; + edges_counter++; + if (src > V) + V = src; + } + if (count == 1) { + dest = strToInt(token); + edges[edges_counter] = dest; + edges_counter++; + if (dest > V) + V = dest; + } + if (count > 1) { + fprintf(stderr, "[%s] An edge consists of two " + "nodes separated by a dash\n", pname); + free(str); + exit(EXIT_FAILURE); + } + switch (src) { + case -2: + free(str); + exit(EXIT_FAILURE); + break; + case -1: + fprintf(stderr, "%s\n", edge); + free(str); + exit(EXIT_FAILURE); + break; + default: + break; + } + + count++; + } + } + + struct Graph *graph = createGraph(V+1); + for (int i = 0; i < (sizeof(edges) / sizeof(int)); i+=2) { + addEdge(graph, edges[i], edges[i+1]); + } + + return graph; +} + +void printGraph(struct Graph *graph) +{ + for (int v = 0; v < graph->V; v++) { + struct AdjListNode* pCrawl = graph->array[v].head; + printf("\n Adjacency list of vertex %d\n head ", v); + while (pCrawl) { + printf("-> %d", pCrawl->dest); + pCrawl = pCrawl->next; + } + printf("\n"); + } +} + int main(int argc, char *argv[]) { if (argc == 1) @@ -40,7 +177,9 @@ int main(int argc, char *argv[]) sigaction(SIGTERM, &sa, NULL); while (quit == 0) { - + struct Graph *graph = parse(argc, argv); + printGraph(graph); + break; } return 0;