基本思想
-用一维数组存储顶点:描述顶点相关的数据
-用二维数组存储边:描述顶点间的关系和权
邻接矩阵法
-设图A = (V,E)是一个有n个顶点的图,图的邻接矩阵为Edge[n][n],则:
Edge[i][i] = w,w权值,i和j连接;空,i == j或i 和j不连接
注:解决工程问题时,习惯于对图中的每个顶点进行编号,当不需要权值时,去w非空表示结点间的有连接
邻接矩阵法实例一
-无向图的邻接矩阵是对称的
-有向图的邻接矩阵可能是不对称的
设计与实现
实现方式一:直接使用数组表示顶点集和边集
template<int N,typename V,typename E>
class MatrixGraph : public Graph<V,E>
{
protected:
V m_vertexes[N];
E m_edges[N][N];
int m_eCoount;
public:
// ...
}
问题
-构造效率低下
·图对象初始化时,频繁调用顶点类型和边类型的构造函数
-空间使用率低下
·图对象占用大量空间,而大多数空间处于闲置状态
-无法表示空值
·无法用同一的方式表示边为空的情形
实现方式二:使用指针数组表示顶点集和边集
template <int N,typename V,typename E>
class MatrixGraph : public Graph<V,E>
{
protected:
V* m_vertexes[N];
E* m_edges[N][N];
int m_eCount;
public:
// ...
}
问题的解决
-构造效率
·初始化图像对象时,只需要将数组元素赋值为空
-空间使用率
·顶点数据元素和边数据元素在需要时动态创建
-空值的表示
·任意的顶点类型和边类型都使用NULL表示空值
存储结构
-邻接矩阵法使用数组对图相关的数据进行存储
-一维数组存储顶点相关的数据(空表无相关数据)
-二维数组存储边相关的数据(空表顶点间无连接)
-代码实现是使用指针数组进行数据的存储(提高效率)
邻接矩阵法中的残留问题
-无法动态添加/删除顶点!!!
二、
基本思想
-为了进一步提高空间使用率,可以考虑使用链表换数组,将临界矩阵变换我邻接链表
邻接链表法
-图中所有顶点按照编号存储于同一个链表中
-每一个顶点对应一个链表,用于存储始发于改顶点的边
-每一条边的信号包含:起点,终点,权值
邻接链表法示例
边数据类型的设计
strcut Edge : public Object
{
int b; //起始顶点
int e; //邻接顶点
E data; //权值
};
顶点数据类型的设计
strcut Vertex : public Object
{
V* data; //顶点数据元素值
LinkList<Edge> edge; //邻接与该顶点的边
//...
};
动态增加/删除顶点
-int addVertex();
·增加新的顶点,返回顶点编号
-int addVertex(const V& value);
·增加新顶点的同事附加数据元素
-void removeVertex();
·删除最近增加的顶点
总结:
-邻接链表法使用链表对图相关的数据进行存储
-每一个顶点关联一个链表,用于存储边相关的数据
-所有顶点按照编号被组织咋同一个链表中
-邻接链表法实现的图能够支持动态添加删除/顶点