我们以下所讨论的图假定为不带自环的简单图,并且以有向边表达所有的连边。利用图论的知识,我们可以采用邻接矩阵来表示点与点之间的连边关系。设一个图具有n个顶点,则可以使用一个n*n的方阵来表示从点i到点j之间是否存在有向边。为了方便操作邻接矩阵,我们需要图(graph)、顶点(vertex)、边(edge)三种数据类型来描述一个完整的图结构。
作为抽象数据类型,图所支持的操作接口分为顶点和边两类:
一、顶点类
1.总顶点数:n()
2.插入顶点:insert(v)
3.删除顶点:remove(v)
4.读取入度:inDegree(v)
5.读取出度:outDegree(v)
6.读取状态:status(v)
7.首个邻接顶点:firstNbr(v)
8.下个邻接顶点:nextNbr(v, u)
9.读取访问时间:dTime(v)
10.读取结束时间:fTime(v)
11.遍历树中的权重:priority(v)
12.遍历树中的父节点:parent(v)
二、边类
1.总边数:e()
2.是否有边:exist(v, u)
3.插入连边:insert(v, u)
4.删除连边:remove(v, u)
5.边的状态:status(v, u)
6.边的数据:edge(v, u)
7.边的权重:weight(v, u)
根据以上的抽象数据类型我们就可以写出graph的模板类了。
typedef enum{ UNDISCOVERED, DISCOVERED, VISITED} VStatus;
typedef enum{ UNDETERMINED, TREE, CROSS, FORWARD, BACKWARD} EStatus;
template <typename Tv, typename Te> class graph
{
private:
/*--内部成员--*/
void reset() {}
void BFS();
void DFS();
template <typename PU> void PFS(int, PU);
public:
/*--顶点操作--*/
int n;
virtual int insert(Tv const&) = 0;
virtual Tv remove(int) = 0;
virtual Tv& vertex(int) = 0;
virtual int inDegree(int) = 0;
virtual int outDegree(int) = 0;
virtual int firstNbr(int) = 0;
virtual int nextNbr(int, int) = 0;
virtual VStatus& status(int) = 0;
virtual int& dTime(int) = 0;
virtual int& fTime(int) = 0;
virtual int& parent(int) = 0;
virtual int& priority(int) = 0;
/*--边操作--*/
int e();
virtual bool exist(int, int) = 0;
virtual void insert(int v, int u, Te const& e, int w) = 0;
virtual Te remove(int, int) = 0;
virtual EStatus& status(int, int) = 0;
virtual Te& edge(int, int) = 0;
virtual int& weight(int, int) = 0;
/*--算法--*/
void bfs(int);
void dfs(int);
template <typename PU> void pfs(int, PU)
};
而顶点的模板类如下:
template <typename Tv> struct Vertex
{
Tv data;
int inDegree;
int outDegree;
VStatus status;
int dTime;
int fTime;
int parent;
int priority;
Vertex(Tv const& d = 0)
data(d), status(UNDISCOVERED),
inDegree(0), outDegree(0),
dTime(-1), fTime(-1),
parent(-1), priority(INT_MAX) {}
};
边的模板类如下:
template <typename Te> struct Edge
{
Te data;
int weight;
EStatus status;
Edge(Te const& d, int w)
data(d), weight(w),
status(UNDETERMINED) {}
};