Presentation is loading. Please wait.

Presentation is loading. Please wait.

The Graph Data Structure Mugurel Ionu Andreica Spring 2012.

Similar presentations


Presentation on theme: "The Graph Data Structure Mugurel Ionu Andreica Spring 2012."— Presentation transcript:

1 The Graph Data Structure Mugurel Ionu Andreica Spring 2012

2 The Elements of a Graph Vertices (nodes) –Numbered from 0 to N-1 (N=total number of vertices) Edges –Each edge connects two vertices: (i,j) = edge between i and j –Undirected graphs: the edge (i,j) is equivalent to the edge (j,i) –Directed graphs: the edges are directed (they are sometimes called arcs) => i->j is different from j->i (although they both connect i and j) –We will only consider graphs where no edge occurs twice (and there are no loops) Both vertices and edges can have extra information associated to them (e.g. name, cost) Graphs can be used for modeling many structures, for example: –Road networks –Social relationships

3 Undirected Graph - example N=7 vertices (nodes) Edges –(0,1) –(0,2) –(0,3) –(1,5) –(1,6) –(2,5) –(3,4) –(4,6)

4 Graph Representations Adjacency matrix –A = an NxN matrix –A[i][j] = 1 if the edge (i,j) occurs in the graph (i.e. the vertices i and j are connected by an edge), and 0 otherwise for undirected graphs –A[i][j] = 1 if there is a directed arc from i to j for directed graphs –A is symmetrical (A[i][j] == A[j][i]) for undirected graphs Lists of neighbors –An array of N linked-lists –The list L[i] contains all the neighbors of the vertex i –In the case of directed graphs, the neighbors of a vertex are considered to be those nodes j such that the arch i->j exists (Simplifying) Assumptions –No multiple edges (i,j) –No loops (i,i)

5 Graph Traversals Depth-First Search (DFS) –Mark all the vertices as not visited –Starting vertex S => call dfs(S) –dfs(x) Mark x as visited For y in Neighbors(X): –If (y has not been marked as visited) then call dfs(y) –DFS is the building block for many more advanced algorithms A simple application: check if a graph is connected Breadth-First Search (BFS) –Mark all the vertices as not visited and initialize an empty queue Q –Starting vertex S => insert S into a queue Q (Q.enqueue(S)) and mark S as visited –While Q is not empty: x = Q.dequeue() For y in Neighbors(X): –If (y has not been marked as visited) then »Mark y as visited »Q.enqueue(y) –BFS can be used for computing shortest paths in the graph

6 Using the Adjacency Matrix (Undirected Graph) #include #include "queue1.h" template class Graph { public: int N; char **A; TnodeInfo *nodeInfo; TedgeInfo **edgeInfo; Graph(int numNodes) { int i, j; N = numNodes; // allocate the adjacency matrix A = new char*[N]; for (i = 0; i < N; i++) A[i] = new char[N]; for (i = 0; i < N; i++) for (j = 0; j < N; j++) A[i][j] = 0; // allocate the array with node information nodeInfo = new TnodeInfo[N]; // allocate the matrix of edge information edgeInfo = new TedgeInfo*[N]; for (i = 0; i < N; i++) edgeInfo[i] = new TedgeInfo[N]; } void setNodeInfo(int i, TnodeInfo info) { nodeInfo[i] = info; } TnodeInfo getNodeInfo(int i) { return nodeInfo[i]; } void addEdge(int i, int j) { A[i][j] = A[j][i] = 1; }

7 Using the Adjacency Matrix (cont.) void removeEdge(int i, int j) { A[i][j] = A[j][i] = 0; } void setEdgeInfo(int i, int j, TedgeInfo info) { edgeInfo[i][j] = edgeInfo[j][i] = info; } TedgeInfo getEdgeInfo(int i, int j) { return edgeInfo[i][j]; } ~Graph() { int i; for (i = 0; i < N; i++) { delete A[i]; delete edgeInfo[i]; } delete A; delete edgeInfo; delete nodeInfo; } }; Graph g(7); char* visited; void dfs(int x) { int y; printf("%d\n", x); visited[x] = 1; for (y = 0; y < g.N; y++) if (g.A[x][y] && !visited[y]) dfs(y); } int *dist; void bfs(int S) { Queue Q; int x, y; Q.enqueue(S); visited[S] = 1; dist[S] = 0; while (!Q.isEmpty()) { x = Q.dequeue(); printf("%d: dist=%d\n", x, dist[x]);

8 Using the Adjacency Matrix (cont.) for (y = 0; y < g.N; y++) if (g.A[x][y] && !visited[y]) { visited[y] = 1; dist[y] = dist[x] + 1; Q.enqueue(y); } int main() { int i; g.addEdge(0, 1); g.addEdge(0, 2); g.addEdge(0, 3); g.addEdge(1, 6); g.addEdge(2, 5); g.addEdge(3, 4); g.addEdge(4, 6); g.addEdge(5, 1); visited = new char[g.N]; for (i = 0; i < g.N; i++) visited[i] = 0; printf("DFS:\n"); dfs(4); for (i = 0; i < g.N; i++) visited[i] = 0; dist = new int[g.N]; printf("BFS:\n"); bfs(4); return 0; }

9 Using the Lists of Neighbors (Undirected Graph) #include #include "linked_list.h" #include "queue1.h" template struct list_elem_info { int node; TedgeInfo edgeInfo; }; template class Graph { public: int N; LinkedList > *L; TnodeInfo *nodeInfo; Graph(int numNodes) { N = numNodes; L = new LinkedList<struct list_elem_info > [N]; nodeInfo = new TnodeInfo[N]; } void setNodeInfo(int i, TnodeInfo info) { nodeInfo[i] = info; } TnodeInfo getNodeInfo(int i) { return nodeInfo[i]; } void addEdge(int i, int j) { struct list_elem_info lei_i, lei_j; lei_i.node = j; lei_j.node = i; L[i].addFirst(lei_i); L[j].addFirst(lei_j); } void removeEdge(int i, int j) { struct list_elem > *p;

10 Using the Lists of Neighbors (cont.) p = L[i].pfirst; while (p != NULL) { if (p->info.node == j) break; p = p->next; } // remove the element pointed to by p from L[i] -- code ommitted p = L[j].pfirst; while (p != NULL) { if (p->info.node == i) break; p = p->next; } // remove the element pointed to by p from L[j] -- code ommitted } void setEdgeInfo(int i, int j, TedgeInfo info) { struct list_elem > *p; p = L[i].pfirst; while (p != NULL) { if (p->info.node == j) break; p = p->next; } p->info.edgeInfo = info; p = L[j].pfirst; while (p != NULL) { if (p->info.node == i) break; p = p->next; } p->info.edgeInfo = info; } TedgeInfo getEdgeInfo(int i, int j) { struct list_elem > *p;

11 Using the Lists of Neighbors (cont.) void dfs(int x) { int y; struct list_elem > *p; printf("%d\n", x); visited[x] = 1; p = g.L[x].pfirst; while (p != NULL) { y = p->info.node; if (!visited[y]) dfs(y); p = p->next; } int *dist; void bfs(int S) { Queue Q; int x, y; struct list_elem > *p; p = L[i].pfirst; while (p != NULL) { if (p->info.node == j) break; p = p->next; } return p->info.edgeInfo; } ~Graph() { int i; delete nodeInfo; for (i = 0; i < N; i++) while (!L[i].isEmpty()) L[i].removeFirst(); delete L; } }; Graph g(7); char* visited;

12 Using the Lists of Neighbors (cont.) int main() { int i; g.addEdge(0, 1); g.addEdge(0, 2); g.addEdge(0, 3); g.addEdge(1, 6); g.addEdge(2, 5); g.addEdge(3, 4); g.addEdge(4, 6); g.addEdge(5, 1); visited = new char[g.N]; for (i = 0; i < g.N; i++) visited[i] = 0; printf("DFS:\n"); dfs(4); for (i = 0; i < g.N; i++) visited[i] = 0; dist = new int[g.N]; printf("BFS:\n"); bfs(4); return 0; } Q.enqueue(S); visited[S] = 1; dist[S] = 0; while (!Q.isEmpty()) { x = Q.dequeue(); printf("%d: dist=%d\n", x, dist[x]); p = g.L[x].pfirst; while (p != NULL) { y = p->info.node; if (!visited[y]) { visited[y] = 1; dist[y] = dist[x] + 1; Q.enqueue(y); } p = p->next; }

13 Implementing Directed Graphs What needs to be changed in the previous two implementations in order to have directed graphs instead of undirected graphs ?


Download ppt "The Graph Data Structure Mugurel Ionu Andreica Spring 2012."

Similar presentations


Ads by Google