对于有向平凡图,只需使用邻接矩阵就可以轻松的表示出点与点之间的连边关系。有了前面所述的graph、vertex、edge类型,我们就可以实现邻接矩阵了。
template <typename Tv, typename Te>
class GraphMatrix: public Graph<Tv, Te>
{
private:
vector<vertex<Tv>> V; //顶点集
vector<vector<edge<Te>*>> E; //邻接矩阵
public:
/*--构造与析构函数--*/
GraphMatrix(): n(0), e(0) {}
~GraphMatrix()
{
for (int j = 0; j < n; j ++)
for (int k = 0; k < n; k ++)
delete E[j][k];
}
/*--顶点静态操作--*/
virtual Tv& vertex(int i) { return V[i].data; }
virtual int inDegree(int i) { return V[i].inDegree; }
virtual int outDegree(int i) { return V[i].outDegree; }
virtual int firstNbr(int i) { return nextNbr(i, n); }
virtual int nextNbr(int i, int j) { for (int k = j; (k >0) && !E[i][k].exist(); k --); return k; }
virtual int VStatus& status(int i) { return V[i].status; }
virtual int& dTime(int i) { return V[i].dTime; }
virtual int& fTime(int i) { return V[i].fTime; }
virtual int& parent(int i) { return V[i].parent; }
virtual int& priority(int i) { return V[i].priority; }
/*--顶点动态操作--*/
virtual int insert(Tv const& d)
{
for (int j = 0; j < n; j ++) E[j].insert(NULL);n ++;
E.insert(vector<edge<Te>*>(n, n, (edge<Te>*) NULL));
return V.insert(Vertex<Tv>(d));
}
virtual int remove(int i)
{
for (int j = 0; j < n; j ++)
if (exist(i, j)) { delete E[i][j]; V[j].inDegree--; }
E.remove(i); n --;
for (int k = 0; k < n; k ++)
if (exist(k, i)) { delete E[k].remove(i); V[j].outDegree--; }
Tv vBack = vertex(i);
V.remove(i);
return vBack;
}
/*--边静态操作--*/
virtual bool exist(int i, int j)
{ return (0 <= i)&&(i < n)&&(0 <= j)&&(j < n)&&(E[i][j] != NULL); }
virtual EStatus& status(int i, int j) { return E[i][j].status; }
virtual Te& edge(int i, int j) { return E[i][j].edge; }
virtual int& weight(int i, int j) { return E[i][j].weight; }
/*--边动态操作--*/
virtual void insert(int i, int j, Te const& edge, int w)
{
if (exist(i, j)) return;
E[i][j] = new Edge<Te>(edge, w);
e ++;
V[i].outDegree ++;
V[j].inDegree ++;
}
virtual Te remove(int i, int j)
{
Te eBack = edge(i, j);
delete E[i][j];
E[i][j] = NULL;
e --;
V[i].outDegree --;
V[j].inDegree --;
return eBack;
}
}