1.图的分类
图分为无权无向图,加权无向图,无权有向图和加权有向图。
我们可以让加权有向图作为超类,其他的图作为他的派生类。
当权值都相同时就相当是无权图了,当凡是有边(i,j)总是有边(j,i)就相当于是无向图了。
为了讨论迪杰斯特拉和Kruskal算法简单,这里我们选用加权无向图。
2.图的实现:
通常图的实现方式有邻接矩阵,邻接链表和邻接数组三种方式。我这选用的邻接矩阵最容易实现。
代码实现如下:
template <class T>
class adjacencyWGraph{
protected:
int n;
int e;
T noEdge;//表示不存在的边的表示方法
public:
T **a;//邻接矩阵
int *reach;//记录是否经历过的数组
int *path_dfs;//记录深度优先搜索的路径
//1.带有默认参数的构造器
adjacencyWGraph(int nV = 0,T theNoEdge =0){
if(nV < 0){
throw "顶点个数必须大于0!";
}
n = nV;
e = 0;
noEdge = theNoEdge;
//创建邻接矩阵
a = new T*[n+1];//数组的数组是二维数组
for (int j = 1; j <=n ; ++j) {
a[j] = new T[n+1];
}
//初始化邻接矩阵
for (int i = 1; i <= n ; ++i) {
for (int j = 1; j <=n ; ++j) {
a[i][j] = noEdge;
}
}
//对reach初始化
reach = new int[n+1];
for (int i = 1; i <= n; ++i) {
reach[i] = 0;
}
//初始化path
path_dfs = new int[n];
for (int k = 0; k < n ; ++k) {
path_dfs[k] = 0;
}
}
~adjacencyWGraph(){
//二维数组的析构方法
for (int i = 1; i <= n; ++i)
{
delete [] a[i];
}
delete [] a;
a = NULL;
delete [] reach;
}
用二维数组a来表示矩阵。在构造函数中对图进行了初始化。reach和path_dfs是记录优先搜索的辅助变量。
其中构造器theNoEdge表示的是(i,j)之间无边有用户给定,一般是一个很大的值。
3.图的一些常规操作
插入边,判断边是否存在,删除边,计算顶点的度
int numberOfVertices() const {
return n;}
int numberOfEdges() const {
return e;}
bool directed() const {
return false;}
bool weighted() const {
return true;}
//2.判断(i,j)边是否存在
bool existsEdge(int i,int j) const{
if (i<1||j<1||i>n||j>n||a[i][j] == noEdge){
return false;
} else{
return true;
}
}
//3.插入边 参数是起点终点和权重