// Graph.C // implementation file for Graph class #include <string> #include <iostream.h> #include "Node.h" #include "Edge.h" #include "Graph.h" #include "Queue.h" // add node with the given name // returns true if the node was added, false if a node with the given // name was already in the graph int Graph::addNode(string name) { int ok = 0; Node *exists = findNode(name); if (exists == NULL) { ok = 1; Node *newNode = new Node(name); if (anchor != NULL) newNode->nextnode = anchor; anchor = newNode; } return ok; } // return pointer to the node with the given name // returns NULL if there is no node with the given name Node* Graph::findNode(string nn) { int found = 0; Node *curr = anchor; while (curr && !found) if (curr->name == nn) found = 1; else curr = curr->nextnode; return curr; } // add edge between the nodes with the given names, if they exist // graph is undirected, so edge is added twice: (from,to) and (to,from) // returns true if the edge is added, false if it couldn't be added because // one or both of the nodes was not found int Graph::addEdge(string from, string to) { int ok = 1; Node *fromnode = findNode(from); Node *tonode = findNode(to); if (fromnode == NULL || tonode == NULL) ok = 0; else { // fromedge is in the edgelist of fromnode and it points to tonode Edge *fromedge = new Edge(tonode); fromedge->nextedge = fromnode->edgelist; fromnode->edgelist = fromedge; // toedge is in the edgelist of tonode and it points to fromnode Edge *toedge = new Edge(fromnode); toedge->nextedge = tonode->edgelist; tonode->edgelist = toedge; } return ok; } // print the nodes and their edges void Graph::print() { Node *curr = anchor; Edge *curredge; // print each node while (curr != NULL) { cout << endl << "Node: " << curr->name << endl; cout << " Edges: " << endl; curredge = curr->edgelist; // print all edges for the current node while (curredge != NULL) { cout << " (" << curr->name << "," << curredge->tonode->name << ")\n"; curredge = curredge->nextedge; } curr = curr->nextnode; } cout << endl; } // private function to unmark all nodes, called by dfs and bfs void Graph::unMarkNodes() { Node *curr = anchor; while (curr != NULL) { curr->mark = 0; curr = curr->nextnode; } } // private function to check if any nodes have mark of 0 // returns pointer to node with mark 0 if found, NULL otherwise Node* Graph::someUnmarked() { int found = 0; Node *curr = anchor; while (curr != NULL && !found) { if (curr->mark == 0) found = 1; else curr = curr->nextnode; } return curr; } // public depth first search: unmarks all nodes, then calls recursive dfs void Graph::dfs() { unMarkNodes(); dfs(anchor); } // depth first search (prints) void Graph::dfs(Node *curr) { Node *nextnode; // mark the current node and get its edge list curr->mark = 1; Edge *curredge = curr->edgelist; // loop through edgelist, dfs any unmarked nodes found on list while (curredge != NULL) { nextnode = curredge->tonode; if (nextnode->mark == 0) { cout << curr->name << " ---> " << nextnode->name << endl; dfs(nextnode); } curredge = curredge->nextedge; } } // breadth first search void Graph::bfs() { unMarkNodes(); bfs(anchor,1); } void Graph::bfs(Node *anch, int markval) { Queue nodes; int ok; Node *currnode; Edge *curredge; nodes.insert(anch); while (!nodes.isEmpty()) { ok = nodes.del(currnode); currnode->mark = markval; curredge = currnode->edgelist; while (curredge) { if (curredge->tonode->mark == 0) nodes.insert(curredge->tonode); curredge = curredge->nextedge; } } } void Graph::connectedComp() { Node *curr; int mark = 1; int found = 1; unMarkNodes(); while (curr = someUnmarked()) { bfs(curr,mark); mark++; } mark = 1; while (found) { cout << "\nConnected component " << mark << ":\n"; curr = anchor; found = 0; while (curr != NULL) { if (curr->mark == mark) { found = 1; cout << " " << curr->name << endl; } curr = curr->nextnode; } mark++; } }
Email Me |
Office Hours |
My Home Page |
Department Home |
MCC Home Page
© Copyright Emmi Schatz 2001