Skip to content

Instantly share code, notes, and snippets.

@marsgpl
Last active December 5, 2023 06:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marsgpl/0a5366c62102b983b23d6f1e8eb0cbd6 to your computer and use it in GitHub Desktop.
Save marsgpl/0a5366c62102b983b23d6f1e8eb0cbd6 to your computer and use it in GitHub Desktop.
graph.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct graph_node {
char *name;
struct graph_node *parent;
struct graph_node **children;
size_t children_size;
size_t children_n;
} node;
typedef struct graph {
node *root;
} graph;
graph *create_graph(node *root);
node *create_node(const char *name);
void push_node(node *parent, node *n);
void trace_graph(graph *g);
void trace_node(node *n, int depth);
void destroy_graph(graph *g);
void destroy_node(node *n);
int main(void) {
node *cat = create_node("cat");
node *paw = create_node("paw");
graph *g = create_graph(cat);
push_node(cat, paw);
push_node(cat, create_node("tail"));
push_node(cat, create_node("ear"));
push_node(paw, create_node("claw"));
trace_graph(g);
destroy_graph(g);
return 0;
}
graph *create_graph(node *root) {
graph *g = malloc(sizeof(graph));
g->root = root;
return g;
}
node *create_node(const char *name) {
node *n = malloc(sizeof(node));
n->name = malloc(sizeof(name));
n->parent = NULL;
n->children = NULL;
n->children_size = 0;
n->children_n = 0;
memcpy(n->name, name, strlen(name) + 1);
return n;
}
void push_node(node *parent, node *n) {
n->parent = parent;
if (parent->children_n == parent->children_size) {
if (parent->children_size == 0) {
parent->children_size = 1;
} else {
parent->children_size *= 2;
}
parent->children = realloc(
parent->children,
parent->children_size * sizeof(node));
}
parent->children[parent->children_n++] = n;
}
void trace_graph(graph *g) {
trace_node(g->root, 0);
}
void trace_node(node *n, int depth) {
if (n == NULL) { return; }
printf("%*s%s%s\n", depth * 2, "", depth ? "- " : "", n->name);
for (size_t i = 0; i < n->children_n; ++i) {
trace_node(n->children[i], depth + 1);
}
}
void destroy_graph(graph *g) {
if (g == NULL) { return; }
destroy_node(g->root);
free(g);
}
void destroy_node(node *n) {
if (n == NULL) { return; }
free(n->name);
for (size_t i = 0; i < n->children_n; ++i) {
destroy_node(n->children[i]);
}
free(n->children);
free(n);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment