Representing Graphs and Networks in C
A Graph is a data structure that consists of a set of nodes interconnected by directed or un-directed arcs. For a DIRECTED Graph, the ordered pair of nodes are written within angled brackets while for a UN-DIRECTED Graph, they are written within parenthesis. Consider a directed graph as depicted below –

Below are the main point to note about the above graph –
- NODE B is said to be ADJACENT to A since there is an arc from A to B.
- INDEGREE – Number of arcs incident to a node. eg: indegree of B is 2
- OUTDEGREE – Number of arcs incident from a node. eg: outdegree of A is
- Now there are 2 CYCLES from from A to A – 1 from E to E, 2 from D to D and 2 from B to B.
- PATHS from node A to D is of length 1 and length 2
- There are 6 paths from A to C of lengths 2, 2, 3, 3, 6, 6 respectively.
Consider a RELATION, R = {<3,10>, <5,6>, <5,8>, <6,17>, <8,17>, <10,17>}. This relation could be represented as a WEIGHTED GRAPH or a NETWORK as shown below –

The weight of each arc is 1 which is value of rem(predecessor node/successor node). Relation is {(x,y) / y > x and rem. of y/x is 1}.
General sequential representation of Graphs in C
Below is a complete sequential representation of graphs in C. It is assumed that nodes have data and arcs are weighted.
# define MAXNODES 50
/*Declaration*/
struct node {
int info;
};
struct arc {
int adj;
int weight;
};
struct graph {
struct node nodes[MAXNODES];
struct arc arcs[MAXNODES][MAXNODES];
}g;
/*Routine to add information to a node*/
void addinfo(struct graph g, int inf, int node1){
g.nodes[node1].info = inf;
return;
}/*end addinfo*/
/*Routine to join a weighted arc from node 1 to node 2*/
void joinwt(struct graph g, int node1, int node2, int Wt){
g.arcs[node1][node2].adj = TRUE;
g.arcs[node1][node2].weight = Wt;
}/*end joinwt*/
/*Routine to remove an arc*/
void remove(struct graph g, int node1, int node2){
g.arcs[node1][node2].adj = FALSE;
g.arcs[node1][node2].weight = NULL;
}/*end remove*/
/*Routine to check for adjacency*/
void adjacent(struct graph g, int node1, int node2){
return((g.arcs[node1][node2].adj == TRUE) ? TRUE : FALSE);
g.arcs[node1][node2].weight = NULL;
}/*end adjacent*/
In the sequential representation above, nodes and the information associated with them are stored in an array nodes[]. The ADJACENCY or arcs are created or removed between two nodes i and j using 2D array g.arcs[i][j] where g.arcs[i][j].adj represents the adjacency (arc) and g.arcs[i][j] weight gives the associated weight. g.arcs[i][j] is calles the ADJACENCY MATRIX of order (MAXNODES – 1) x (MAXNODES – 1).
TRANSITIVE CLOSURE – PATH MATRIX of length n
If we consider that a graph is totally defined by the adjacency matrix such that the nodes have no info field and arcs are not weighted where Adjacency Matrix aij is defined as –
aij = { 1, if there exists an adjacency or arc between two nodes i and j.
0, otherwise
}
For such graphs, we use the TRANSITIVE PROPERTY OF GRAPHS to check for the path between two nodes. Consider a graph completely represented as an adjacency matrix.

Now the adjacency matrix adj could be written as –

Likewise we could obtain the path matrices upto k where k is the max number of nodes from the boolean product of path matrix of length k-1 and adj.
Matrix Path or Transitive Closure = adj || adj2 || adj3 || ………………….. || adjk
Such a matrix path is often called the Transitive Closure of adj matrix. For the above gaph, the transitive closure is –
Transitive Closure (Matrix Path) = adj || adj2 || adj3 || adj4 || adj5 (k=5)
Complete Adjacency Matrix representation of Graphs in C
In such a case, we consider that the nodes have no info associated with it and arcs have no weights associated with them.
Arcs with no weights
# define MAXNODES 50
/*Declaration*/
int adj[MAXNODES][MAXNODES];
/*Routine joining arcs*/
void join(int adj[][MAXNODES], int node1, int node2){
adj[node1][node2] = TRUE;
}/*end join*/
/*Routine for removing arcs*/
void remove(int adj[][MAXNODES], int node1, int node2){
adj[node1][node2] = FALSE;
}/*end remove*/
/*Routine to check for adjacency*/
void adjacent(int adj[][MAXNODES], int node1, int node2){
return((adj[node1][node2] == TRUE) ? TRUE : FALSE);
}/*end adjacent*/
Arcs with weights
# define MAXNODES 50
struct arc {
int adj;
int weight;
};
/*Declaration*/
struct arc g[MAXNODES][MAXNODES];
/*Routine to join a weighted arc from node 1 to node 2*/
void joinwt(struct g[MAXNODES][MAXNODES], int node1, int node2, int Wt){
g[node1][node2].adj = TRUE;
g[node1][node2].weight = Wt;
}/*end joinwt*/
/*Routine to remove an arc*/
void remove(struct g[MAXNODES][MAXNODES], int node1, int node2){
g[node1][node2].adj = FALSE;
g[node1][node2].weight = NULL;
}/*end remove*