#ifndef GRAPHMATRIX_H_ #define GRAPHMATRIX_H_ #include "Graph.h" #include "Edge.h" #include "Vertex.h" #include "../chp2/Vector.h" template class GraphMatrix: public Graph{ private: Vector> V; Vector*>> E; public: //constructor GraphMatrix(); //deconstructor ~GraphMatrix(); //implementations of abstract Graph methods //vertex methods int insertVertex(Tv const& data); //return the id number of the new vertex Tv removeVertex(int vertexId); Tv& vertex(int vertexId) { return V[vertexId].data; } int inDegree(int vertexId) { return V[vertexId].inDegree; } int outDegree(int vertexId) { return V[vertexId].outDegree; } int firstNeighbor(int vertexId); int nextNeighbor(int vertexId, int curr); int& dtime(int vertexId) { return V[vertexId].dTime; } int& ftime(int vertexId) { return V[vertexId].fTime; } int& parent(int vertexId) { return V[vertexId].parent; } int& priority(int vertexId) { return V[vertexId].priority; } VStatus& status(int vertexId) { return V[vertexId].status; } //directed edge methods bool exists(int src, int tail) { return E[src][tail] != nullptr; } void insertEdge(Te const &data, int src, int tail) { insertEdge(data, 1, src, tail); } void insertEdge(Te const &data, double weight, int src, int tail); Te removeEdge(int src, int tail); Etype& type(int src, int tail) { return E[src][tail]->type; } Te& edge(int src, int tail) { return E[src][tail]->data; } double& weight(int src, int tail) { return E[src][tail]->weight; } }; //application interfaces void graph_demo(GraphMatrix &G); /*---------------Implementations---------------*/ //constructor template GraphMatrix::GraphMatrix(){ num_of_vertices = 0; num_of_edges = 0; } //deconstructor template GraphMatrix::~GraphMatrix(){ for (int ix = 0; ix != num_of_vertices; ++ix) for (int jx = 0; jx != num_of_vertices; ++jx) if (exists(ix, jx)) delete E[ix][jx]; } //implementations of abstract Graph methods //vertex methods template int GraphMatrix::insertVertex(Tv const & data){ V.push_back(Vertex(data)); for (int ix = 0; ix != num_of_vertices; ++ix) E[ix].push_back(nullptr); E.push_back(Vector*>(++num_of_vertices, nullptr)); return num_of_vertices - 1; } template Tv GraphMatrix::removeVertex(int vertexId){ for (int ix = 0; ix != num_of_vertices; ++ix) if (exists(vertexId, ix)) removeEdge(vertexId, ix); for (int ix = 0; ix != num_of_vertices; ++ix) { if(exists(ix, vertexId)) removeEdge(ix, vertexId); E[ix].pop(vertexId); } E.pop(vertexId); num_of_vertices--; return V.pop(vertexId).data; } template int GraphMatrix::firstNeighbor(int vertexId) { return nextNeighbor(vertexId, num_of_vertices); } template int GraphMatrix::nextNeighbor(int vertexId, int curr) { while(0 <= --curr){ if (exists(vertexId, curr)) break; } return curr; } //edge methods template void GraphMatrix::insertEdge(Te const &data, double weight, int src, int tail){ if (src < 0 || src >= num_of_vertices || tail < 0 || tail >= num_of_vertices) return; if (exists(src, tail)) return; E[src][tail] = new Edge(data, weight); ++num_of_edges; V[tail].inDegree++; V[src].outDegree++; } template Te GraphMatrix::removeEdge(int src, int tail){ Te edgeBak = edge(src, tail); delete E[src][tail]; E[src][tail] = nullptr; --num_of_edges; V[tail].inDegree--; V[src].outDegree--; return edgeBak; } #endif