Graph C and Data Structures Baojian Hua
What ’ s a Graph? Graph: a group of vertices connected by edges
Why Study Graphs? Interesting & broadly used abstraction not only in computer science challenge branch in discrete math Ex: the 4-color problem hundreds of known algorithms with more to study numerous applications
Broad Applications GraphVerticesEdges communicationtelephonecables softwarefunctionscalls internetweb pagehyper-links social relationship peoplefriendship transportationcitiesroads ………
Graph Terminology node edge: directed vs undirected
Graph Terminology degree: in-degree vs out-degree
Graph ADT A graph is a tuple (V, E) where V is a set of vertices v1, v2, … and E is a set of vertex tuple Typical operations: graph creation search a vertex (or an edge) traverse all graph vertexes …
Example G = (V, E) V = {1, 2, 3, 4, 5, 6} E = {(1, 2), (2, 5), (5, 4), (4, 1), (4, 2), (3, 5), (3, 6), (6, 6)}
“ graph ” ADT in C: Interface // We assume, in this slides, all graphs directed, // and undirected ones are similar and easier. // in file “graph.h” #ifndef GRAPH_H #define GRAPH_H typedef struct graph *graph; graph new (); void insertVertex (graph g, poly x); void insertEdge (graph g, poly from, poly to); // we’d see more later … #endif
Client Code graph g = newGraph (); insertVertex (g, 1); insertVertex (g, 2); … insertEdge (g, 1, 2); insertEdge (g, 2, 5); …
Implementation We ’ d study two impl ’ strategies: array-based for vertex v0, v1, …, vn, keep a two dimension array G[n+1][n+1] G[i][j] holds the edge, if there exists one linear list-based for every vertex vi, maintain a linear list l l stores vi ’ s adjacent vertices
Implementation#1: Adjacency Matrices // A simplified version (no edge info): #define initSize 4 struct graph { int (*matrix)[initSize][initSize]; int maxSize; int curSize; }; matrix maxSize g curSize
graph new () { graph g = checkedMalloc (sizeof (*g)); g->matrix = checkedMalloc (sizeof (g->matrix)); for (int i=0; i<initSize; i++) for (int j=0; j<initSize; j++) (g->matrix)[i][j] = 0; g->maxSize = initSize; g->curSize = -1; return g; }
new () matrix maxSize g curSize=-1
insertVertex (graph g, poly x) void insertVertex (graph g, poly x) { // assign each vertex x a number (array index) // maintain a dictionary internally int index = assignIndex (x); if (index >= g->maxSize) { // extend the array, just like the extArray extendArray (g->matrix); g->maxSize = …; //depends on extension factor } g->curSize ++; return; }
insertVertex on This Graph graph g = newGraph (); insertVertex (g, 1); insertVertex (g, 2); … // suppose we have this mapping: 1==>0; 2==>1; …
insertVertex matrix maxSize g curSize=4 After inserting vertex 1, 2, 3, 4; the matrix is full, so we ’ d extend it. Suppose the extension factor is 2.
insertVertex matrix maxSize g curSize=
insertEdge (graph g, poly from, poly to) void insertEdge (graph g, poly from, poly to) { // assign vertex from, to numbers (array index) // maintain internal a mapping int indexFrom = assignIndex (from); int indexTo = assignIndex (to); (g->matrix)[indexFrom][indexTo] = 1; return; }
insertVertex on This Graph graph g = newGraph (); insertEdge (g, 1, 2); insertEdge (g, 2, 5); …
insertVertex matrix maxSize g curSize=
Moral We should keep a dictionary (symbol table) to record and assign array index to graph vertex any representation strategy should do the dictionary should be kept in the graph Information in the matrix is too coarse we may want to associate some info (say weight) with graph edges Need a more fancy version of array slots
More Fancy Edge Definition // define a more fancy edge: typedef struct edge *edge; struct edge { int from; int to; poly info; };
Adjacency Matrices // A simplified version: #define initSize 4 struct graph { edge (*matrix)[initSize][initSize]; int maxSize; int curSize; }; matrix maxSize g curSize
insertEdge (graph g, poly from, poly to) void insertEdge (graph g, poly from, poly to, poly edgeInfo) { // assign vertex from, to numbers (array index) int indexFrom = assign (from); int indexTo = assign (to); edge e = newEdge (indexFrom, indexTo, edgeInfo); (g->matrix)[indexFrom][indexTo] = e; return; }
Implementation#2: Adjacency Lists // in file “alGraph.c” struct graph{ poly info; struct succ *succs; struct graph *next; }; struct succ{ struct graph *v; struct succ *next; }; info succs next info succs next v v v /\
Or With Edges struct graph{ poly info; struct edge *edges; struct graph *next; }; struct edge { struct vertex *from; struct vertex *to; struct edge *next; }; info edges next from next to /\
Use of Linear List // syntax T is not supported by C, which is // put here for illustrative purpose struct graph{ list vertices; }; struct vertex{ poly info; list edges; }; struct edge{ struct vertex *from; struct vertex *to; } info edges next from next to /\
graph new () { graph g = checkedMalloc (sizeof (*g)); g->vertices = newLinkedList (); return g; } /\ g
insertVertex (graph g, poly x) void insertVertex (graph g, poly x) { vertex v = newVertex (x); linkedListInsertHead (g->vertices, v); return; } // with void newVertex (poly x){ vertex v = checkedMalloc (sizeof (*v)); v->info = x; v->edges = newLinkedList (); return v; }
insertVertex on This Graph graph g = newGraph (); insertVertex (g, 1); insertVertex (g, 2); …
Example of InsertVertex next data g /\
insertEdge (graph g, poly from, poly to) void insertEdge (graph g, poly from, poly to) { vertex f = searchVertex (g->vertices, from); vertex t = searchVertex (g->vertices, to); edge e = newEdge (f, t); linkedListInsertHead (f->edges, e); return; }
insertVertex on This Graph graph g = newGraph (); insertEdge (g, 1, 2); insertVertex (g, 2, 5); …
Example of InsertEdge next data g /\ from to from to