Vous êtes sur la page 1sur 4

// Graph.c ...

implementation of Graph ADT


// Written by John Shepherd, May 2013
#include
#include
#include
#include
#include
#include

<stdlib.h>
<stdio.h>
<assert.h>
<string.h>
"Graph.h"
"Queue.h"

#define TRUE 1
#define FALSE 0
// graph representation (adjacency matrix)
typedef struct GraphRep {
int
nV;
// #vertices
int
nE;
// #edges
int **edges; // matrix of weights (0 == no edge)
} GraphRep;
// check validity of Vertex
int validV(Graph g, Vertex v)
{
return (g != NULL && v >= 0 && v < g->nV);
}
// make an edge
Edge mkEdge(Graph g, Vertex v, Vertex w)
{
assert(g != NULL && validV(g,v) && validV(g,w));
Edge new = {v,w}; // struct assignment
return new;
}
// insert an Edge
// - sets (v,w) and (w,v)
void insertEdge(Graph g, Vertex v, Vertex w, int wt)
{
assert(g != NULL && validV(g,v) && validV(g,w));
if (g->edges[v][w] == 0) {
g->edges[v][w] = wt;
g->edges[w][v] = wt;
g->nE++;
}
}
// remove an Edge
// - unsets (v,w) and (w,v)
void removeEdge(Graph g, Vertex v, Vertex w)
{
assert(g != NULL && validV(g,v) && validV(g,w));
if (g->edges[v][w] != 0) {
g->edges[v][w] = 0;
g->edges[w][v] = 0;
g->nE--;
}
}
// create an empty graph
Graph newGraph(int nV)

{
assert(nV > 0);
int v, w;
Graph new = malloc(sizeof(GraphRep));
assert(new != 0);
new->nV = nV; new->nE = 0;
new->edges = malloc(nV*sizeof(int *));
assert(new->edges != 0);
for (v = 0; v < nV; v++) {
new->edges[v] = malloc(nV*sizeof(int));
assert(new->edges[v] != 0);
for (w = 0; w < nV; w++)
new->edges[v][w] = 0;
}
return new;
}
// free memory associated with graph
void dropGraph(Graph g)
{
assert(g != NULL);
// not needed for this lab
}
// display graph, using names for vertices
void showGraph(Graph g, char **names)
{
assert(g != NULL);
printf("#vertices=%d, #edges=%d\n\n",g->nV,g->nE);
int v, w;
for (v = 0; v < g->nV; v++) {
printf("%d %s\n",v,names[v]);
for (w = 0; w < g->nV; w++) {
if (g->edges[v][w]) {
printf("\t%s (%d)\n",names[w],g->edges[v][w]);
}
}
printf("\n");
}
}
// find a path between two vertices using breadth-first traversal
// only allow edges whose weight is less than "max"
int findPath(Graph g, Vertex src, Vertex dest, int max, int *path)
{
assert(g != NULL && validV(g,src) && validV(g, dest));
// dest and src are the same location,
if (src == dest) {
path[0] = dest;
return 1;
}
// array to keep track of visited vertices
int *visited = malloc(g->nV * sizeof(int));
Vertex pred[g->nV];
// initialize elements in visited array
int i;
for(i = 0; i < g->nV; i++){

pred[i] = -1;
}
// put starting location into queue
Queue queue = newQueue();
QueueJoin(queue, src);
int isFound = FALSE;
// while there are still items in queue AND haven't reached destination
yet
while(!QueueIsEmpty(queue) && !isFound){
//grab next connected vertex to check from queue
//both x and y need to be the same vertex, cannot be 2 diff leav
e queues
Vertex y,x = QueueLeave(queue);
//skip this loop
if (visited[x]){
continue;
}
visited[x] = 1;
for (y = 0; y < g->nV; y++) {
// if edge weight is more than max - skip
// if it is the same city - skip
if (g->edges[x][y] > max || g->edges[x][y] == 0){
continue;
}
// hasnt been visited
if (!visited[y]){
QueueJoin(queue,y);
if (pred[y] == -1){
pred[y] = x;
}
// if destination is found we can stop the loop
all tgt
if (y == dest){
isFound = TRUE;
}
}
}
}
//after it is found, count the number of hops it took
if (isFound){
int hops = 0;
Vertex curr = dest;
while (curr != src) {
hops++;
curr = pred[curr];
}
curr = dest;
int i = hops;
for(; i >= 0; i--){
path[i] = curr;
curr = pred[curr];
}

return hops+1;
}
return 0; // never find a path ... you need to fix this
}

Vous aimerez peut-être aussi