#include #include #include #include #include #include struct graph { dlist *nodes; // The graph nodes are stored in a directed list int max_nodes; // int connected; }; struct node { void *value; bool seen; dlist *edge; }; // ===========INTERNAL FUNCTION IMPLEMENTATIONS ============ /** * node_create() - Allocate and populate a graph entry. * @key: A pointer to a function to be used to compare keys. * @value: A pointer to a function (or NULL) to be called to * de-allocate memory for keys on remove/kill. * * Returns: A pointer to the newly created graph entry. */ node *node_create(const void *value, int max_node) { // Allocate space for a graph entry. Use calloc as a defensive // measure to ensure that all pointers are initialized to NULL. node *e = calloc(1, sizeof(*e)); // Populate the entry. e->value = value; e->seen = false; e->edge = dlist_empty(NULL); // lista med tillhörande edges return e; } /** * node_kill() - Return the memory allocated to a graph entry. * @e: The graph entry to deallocate. * * Returns: Nothing. */ void node_kill(void *v) { node *e = v; // Convert the pointer (useful if debugging the code) // All we need to do is to deallocate the struct. free(e); } /** * graph_empty() - Create an empty graph. * @key_cmp_func: A pointer to a function to be used to compare keys. * @key_kill_func: A pointer to a function (or NULL) to be called to * de-allocate memory for keys on remove/kill. * @value_kill_func: A pointer to a function (or NULL) to be called to * de-allocate memory for values on remove/kill. * * Returns: Pointer to a new graph. */ graph *graph_empty(int max_nodes) { // Allocate the graph header. graph *g = calloc(1, sizeof(graph)); // Create the list to hold the node-ies. g->nodes = dlist_empty(NULL); g->max_nodes = max_nodes; // Store the key compare function and key/value kill functions. return g; } /** * graph_is_empty() - Check if a graph is empty. * @graph: graph to check. * * Returns: True if graph contains no entries, false otherwise. */ bool graph_is_empty(const graph *g) { return dlist_is_empty(g->nodes); } graph *graph_insert_node(graph *g, const char *s) { node *e = node_create(s, g->max_nodes); //e->seen = false; dlist_insert(g->nodes, e, dlist_first(g->nodes)); return g; } bool nodes_are_equal(const node *n1, const node *n2) { if (n1 == NULL || n2 == NULL) { return n1 == n2; } return strcmp(n1->value, n2->value) == 0; } bool graph_has_edges(const graph *g) { dlist_pos pos = dlist_first(g->nodes); while (!dlist_is_end(g->nodes, pos)) { node *e = dlist_inspect(g->nodes, pos); if (!dlist_is_empty(e->edge)) { return true; } pos = dlist_next(g->nodes, pos); } return false; } node *graph_find_node(const graph *g, const char *s) { dlist_pos pos = dlist_first(g->nodes); while (!dlist_is_end(g->nodes, pos)) { node *e = dlist_inspect(g->nodes, pos); if (strcmp(e->value, s) == 0 && !e->edge) { return e; } pos = dlist_next(g->nodes, pos); } return NULL; } bool graph_node_is_seen(const graph *g, const node *n) { dlist_pos pos = dlist_first(g->nodes); while (!dlist_is_end(g->nodes, pos)) { node *e = dlist_inspect(g->nodes, pos); if (nodes_are_equal(e, n) && e->edge == false) { return e->seen; } pos = dlist_next(g->nodes, pos); } return false; } graph *graph_node_set_seen(graph *g, node *n, bool seen) { dlist_pos pos = dlist_first(g->nodes); while (!dlist_is_end(g->nodes, pos)) { node *e = dlist_inspect(g->nodes, pos); if (nodes_are_equal(e, n) && e->edge == false) { e->seen = seen; break; } pos = dlist_next(g->nodes, pos); } return g; } graph *graph_reset_seen(graph *g) { dlist_pos pos = dlist_first(g->nodes); while (!dlist_is_end(g->nodes, pos)) { node *e = dlist_inspect(g->nodes, pos); if (e->seen == true) { e->seen = false; } pos = dlist_next(g->nodes, pos); } return g; } graph *graph_insert_edge(graph *g, node *n1, node *n2) { dlist_insert(n1->edge, n2, dlist_first(n1->edge)); return g; } dlist *graph_neighbours(const graph *g,const node *n) { return n->edge; } void graph_print(const graph *g) { dlist_pos pos = dlist_first(g->nodes); while (!dlist_is_end(g->nodes, pos)) { node *e = dlist_inspect(g->nodes, pos); printf("%s to nodes: ", (char *)e->value); dlist_pos pos_edge = dlist_first(e->edge); while (!dlist_is_end(e->edge, pos_edge)) { node *edges = dlist_inspect(e->edge,pos_edge); printf("%s,", (char *)edges->value); pos_edge = dlist_next(e->edge, pos_edge); } printf("\n"); pos = dlist_next(g->nodes, pos); } }