1 / 13

The Graph Data Structure

The Graph Data Structure. Mugurel Ionu ț Andreica Spring 2012. 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

kent
Download Presentation

The Graph Data Structure

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

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) 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;} #include <stdio.h> #include "queue1.h" template<typename TnodeInfo,typenameTedgeInfo> 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];

  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<int, int> 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<int> 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.) 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; } 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);

  9. Using the Lists of Neighbors (Undirected Graph) #include <stdio.h> #include "linked_list.h" #include "queue1.h" template<typename TedgeInfo> struct list_elem_info { int node; TedgeInfo edgeInfo; }; template<typename TnodeInfo, typename TedgeInfo> class Graph{ public: int N; LinkedList<struct list_elem_info<TedgeInfo> > *L; TnodeInfo *nodeInfo; Graph(int numNodes){ N = numNodes; L = new LinkedList<struct list_elem_info<TedgeInfo> > [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<TedgeInfo> 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<struct list_elem_info<TedgeInfo> > *p;

  10. Using the Lists of Neighbors (cont.) 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<struct list_elem_info<TedgeInfo> > *p; 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<struct list_elem_info<TedgeInfo> > *p;

  11. Using the Lists of Neighbors (cont.) void dfs(int x){ int y; struct list_elem<struct list_elem_info<int> > *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<int> Q; int x, y; struct list_elem<struct list_elem_info<int> > *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<int, int> g(7); char* visited;

  12. Using the Lists of Neighbors (cont.) 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; } } } 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; }

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

More Related