/********************************************************************************************** * Program Name: graphType.h * Author: Zhixiang Chen * Course: CSCI/CMPE 3333, Fall 2014 * Lab 7: Header file for Lab 7 * Date: 08/2014 * Description: This header contains a graph, emphasizing on depth-first search * Graph representation: Adjacent list is used. And the input graph is weighted. * Input fiel format: Raw data of a graph is stored in a file. The first row has * the number of nodes. the next row gives the adjacent list of the first * node, the third gives the adjacent list of the second node, and so on. ***********************************************************************************************/ #include #include #include #include #include #include #include #include "arrayBasedListType.h" #include "linkedListType.h" #include "stackType.h" #include "queueType.h" #include "heapType.h" using namespace std; #ifndef GRAPH #define GRAPH enum statusType{VISITED, UNVISITED, ACTIVE}; /************************************************************ binary min-heap node type *************************************************************/ struct mhNodeType { double distance; //distance from the source to the current node int label; //lable fo the current node bool operator<(const mhNodeType & rhs); bool operator>(const mhNodeType & rhs); bool operator>=(const mhNodeType & rhs); bool operator==(const mhNodeType & rhs); //{return distance == rhs.distance;} bool operator<=(const mhNodeType & rhs); //{return distance <= rhs.distance;} mhNodeType(); mhNodeType(const mhNodeType & rhs); }; bool mhNodeType::operator<(const mhNodeType & rhs) { return distance < rhs.distance; } bool mhNodeType::operator>(const mhNodeType & rhs) { return distance > rhs.distance; } bool mhNodeType:: operator>=(const mhNodeType & rhs) { return distance >= rhs.distance; } bool mhNodeType:: operator==(const mhNodeType & rhs) { return distance == rhs.distance; } bool mhNodeType:: operator<=(const mhNodeType & rhs) { return distance <= rhs.distance; } mhNodeType::mhNodeType() { distance = static_cast(LONG_MAX); label = -1; } mhNodeType::mhNodeType(const mhNodeType & rhs) { distance = rhs.distance; label = rhs.label; } /************************************************************ graph node type *************************************************************/ struct vertexType { friend ostream & operator<<(ostream & os, vertexType n); int label; //the lable of the node statusType tag; //indicate VISITED, ACTIVE, UNVISITED status double distance; //distance from the source to the current node int parent; //the lable of the parent of the current node bool operator==(vertexType & rhs){return label == rhs.label;} vertexType & operator=(vertexType &); vertexType(); }; ostream & operator<<(ostream & os, vertexType n) { os<(LONG_MAX); } vertexType & vertexType::operator=(vertexType & rhs) { if (this != &rhs) { label = rhs.label; tag = rhs.tag; distance = rhs.distance; parent = rhs.parent; } return *this; } /************************************************************ adjacent list node type *************************************************************/ struct adjVertexType { friend ostream & operator<<(ostream & os, adjVertexType n); int label; //the lable of the node double weight; //save the edge weight bool operator==(adjVertexType & rhs){return label == rhs.label;} adjVertexType & operator=(adjVertexType &); adjVertexType(); }; ostream & operator<<(ostream & os, adjVertexType n) { os< 3) a binary min-heap of mhNodeType *********************************************************************/ class graphType { public: void loadGraph(ifstream & inFile); void saveGraph(ofstream & outFile); void print(); //in adj list format void dfs(int); //depth-first-search void bfs(int); //breadth-first-search void dShortestPath(int start); //Dijkstra shortest path algorithm from start void printShortestPath(int end); //print the shortest path ending at end void printShortestPath(int start, int end); //print shortest path from start to end void setHeapSize(int); //set minHeap size void setSize(int); //set node list and adjacent list sizes graphType & operator=(graphType &); int getSize(){return nodes.length();} graphType(){}; graphType (graphType &); ~graphType(){}; private: arrayListType> adjList; //store the adjacent list arrayListType nodes; binaryHeapType heap; }; /*-------------------------------------------------------------------------- Dijkstra shortest path algorithm from start to all nodes --------------------------------------------------------------------------*/ void graphType:: dShortestPath(int start) { int len = nodes.length(); //get the graph size setHeapSize(len); //prepare the heap to len + 1 int i, j; // deg; mhNodeType m, nm; adjVertexType adjNode; bool more; double cost, oldCost, newCost; //process the starting node i=start; nodes[i].tag=VISITED; nodes[i].distance = 0; //insert nodes adjacent to the starting node into heap more = adjList[i].getNext(adjNode); while (more) { j = adjNode.label; cost = adjNode.weight; nodes[j].distance = cost; nodes[j].parent = i; nodes[j].tag = ACTIVE; nm.distance = cost; nm.label = j; heap.insert(nm); more = adjList[i].getNext(adjNode); } //Here, an active node may be inserted into heap multi times due to new, shorter distance changes while (!heap.isEmpty()) { //remove the min node from the heap and process it heap.deleteMin(m); i = m.label; if (nodes[i].tag==VISITED) continue; //skip the rest loop and start next iteration //here we found next min-node that has not been visited nodes[i].tag = VISITED; //process all the nodes adjacent to m cost = nodes[i].distance; more = adjList[i].getNext(adjNode); while (more) { j = adjNode.label; if (nodes[j].tag != VISITED) { oldCost = nodes[j].distance; newCost = cost + adjNode.weight; if (newCost < oldCost) { nodes[j].distance = newCost; nodes[j].parent = i; if (nodes[j].tag == UNVISITED) { nodes[j].tag = ACTIVE; } nm.distance = newCost; nm.label = j; heap.insert(nm); } } more = adjList[i].getNext(adjNode); } } } /*-------------------------------------------------------------------------- Print the shortest path ending at end --------------------------------------------------------------------------*/ void graphType:: printShortestPath(int end) { int i; double cost; arrayStackType path; //find cost and path cost = nodes[end].distance; i = end; while (true) { path.push(i); i = nodes[i].parent; if (i == -1) break; } cout< "< path; //find cost and path cost = nodes[end].distance; i = end; while (true) { path.push(i); i = nodes[i].parent; if (i == -1) break; } cout< "< queue; vertexType nodeTmp; adjVertexType adjNodeTmp; queue.enQueue(nodes[start]); while(!queue.isEmpty()) { nodeTmp = queue.deQueue(); //pop the top stack node and visit it cout< stack; vertexType nodeTmp; adjVertexType adjNodeTmp; stack.push(nodes[start]); while(!stack.isEmpty()) { nodeTmp = stack.pop(); //pop the top stack node and visit it cout<> len; setSize(len); for (i=0; i>v.label; v.tag = UNVISITED; nodes.insertLast(v); inFile>>deg; for (j=0; j>newLabel>>newWeight; newNode.label = newLabel; newNode.weight = newWeight; adjList[i].insertLast(newNode); } adjList.setCount(); } } /*------------------------------------------------ The output file format is the same as that of the input file format --------------------------------------------------*/ void graphType::saveGraph(ofstream & outFile) { int len, i; adjVertexType newNode; len = nodes.length(); for (i=0; i