Just for kind of "fun" I'm developing almost every algorithm (if possible) shown in the book Introduction to Algorithms (Cormen) in C. I've reached the graphs chapters and I'm not sure how to design my functions, but first take a look at my data structures (hope this will make clear my question).
typedef struct s_multi_matrix
{
int width;
int height;
int depth;
multi_matrix_type type; // stores either MMTYPE_INT or MMTYPE_RECORD enums to know where to read values (ivals or rvals)
int * ivals;
DT_record * rvals;
} DT_multi_matrix;
typedef struct s_double_linked_list
{
DT_record * sentinel;
} DT_double_linked_list;
typedef struct s_record // multi purpose structure
{
int key;
enum e_record_type type; // stores either TYPE_INT, TYPE_SZ, TYPE_FLOAT, TYPE_VOID to know how to use the data union
union
{
int ival;
char * sval;
float fval;
void * vval;
} data;
struct s_record * left, // for trees, disjoint sets and linked lists
* right,
* parent;
} DT_record;
typedef struct s_graph // this is the structure I'm focusing on right now
{
graph_type type; // GRAPH_DIRECTED or GRAPH_UNDIRECTED
graph_adj_type adj_type; // ADJ_LIST or ADJ_MATRIX
edge_type etype; // WEIGHTED or NOT_WEIGHTED
union
{
DT_double_linked_list * list;
DT_multi_matrix * matrix;
} adjacency;
} DT_graph;
So, I'm thinking about several functions to manipulate the DT_graph type:
// takes a pointer to a pointer to a graph, allocates memory and sets properties
void build_graph(DT_graph ** graph_ptr, graph_type gtype, graph_adj_type atype);
// prints the graph in file (using graphviz)
void print_graph(DT_graph * graph, char * graph_name);
This is the tricky part, since my graph type has several different type combinations (undirected and weighted edges, directed and weighted edges, undirected and not weighted edges, directed and not weighed edges, ...) I'm wondering which is the best approach for the functions:
void dgraph_add_wedge(DT_graph * graph, DT_record * u, DT_record * v, int weight);
void ugraph_add_wedge(DT_graph * graph, DT_record * u, DT_record * v, int weight);
void dgraph_add_nwedge(DT_graph * graph, DT_record * u, DT_record * v);
void ugraph_add_nwedge(DT_graph * graph, DT_record * u, DT_record * v);
The first two would add a weighted vertex into a directed / undirected graph and the last two would do the same thing but without any weight related to the edge. The other approach that comes to my mind looks like this:
void graph_add_edge(DT_graph * graph, DT_record * u, DT_record * v, edge_type etype, graph_type gtype);
This seems like a "golden" method for everything, and depending on the values for etype and gtype would do different operations on the graph.
Soooooooo, based upon your experiences and knowledge, what do you recommend?
BTW, I'm sure that any one has asked this before, since this is MY implementation.