一、图的基本概念
1、图的定义
图是由顶点集合及顶点间的关系组成的一组数据结构,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。
我们称之为顶点(Vertex),顶点集合有穷非空。在图中,任意两个顶点之间都可能有关系,顶点之间的逻辑关系用边来表示,边集可以是空的。
2、图的分类
图按照边的有无方向分为无向图和有向图。无向图由顶点和边组成,有向图由顶点和弧构成。弧有弧尾和弧头之分,带箭头一端为弧头。
3、完全图
在有n个顶点的无向图中,若有n*(n-1)/2条边,即任意两个顶点之间有且仅有一条边,就称此图为无向完全图;在n个顶点的有向图中,若有n*(n-1)条边,即任意两个顶点之间有且仅有方向相反的边,则称此图为有向完全图。
4、顶点的度
顶点v的度是指与他相关联的边的条数,记作dev(v)。在有向图中,顶点的度等于该顶点的出度和入度之和,其中顶点v的入度是以v为终点的有像边的条数,记作indev(v);顶点v的出度是以v为起始点的有向边的条数,记作outdev(v);无向图的度为该节点的出度。
5、权
权值是指边附带的数据信息
6、路径
在图G = (V, E)中,若从顶点vi出发有一组边使其可到达顶点vj,则称顶点vi到顶点vj的顶点序列为从顶点vi到顶点vj的路径。
7、路径长度
在不带权的图:一条路径的的路径长度指的是改路径上边的条数
带权的图:一条路径的路径长度是指该路径上各个边权值的总和。
8、子图
设图G = {V, E}和图G1 = {V1,E1},若V1属于V且E1属于E,则称G1是G的子图。
9、连通图
在无向图中,若从顶点v1到顶点v2有路径,则称顶点v1与顶点v2是连通的。如果图中任意一对顶点都是连通的,则称此图为连通图。
10、强连通图
在有向图中,若在每一对顶点vi和vj之间都存在一条从vi到vj的路径,也存在一条从vj到vi的路径,则称此图是强连通图。
二、图的存储结构
在数据结构中,要将图存储起来,就要选择合理的存储结构,不仅要存储每一个顶点,还要存储图关于边的逻辑集合,那么基本的存储结构主要有以下两种:
【邻接矩阵】
1、邻接矩阵
图的邻接矩阵的表示方式需要两个数组来表示图的信息,一个一维数组表示每个数据元素的信息,一个二维数组(邻接矩阵)表示图中的边或者弧的信息。
设图G = (V, E)包含n个顶点,则A的邻接矩阵是一个二维数组G.Edge[n][n],
对于带权值的图,邻接矩阵的定义如下:
无向图的邻接矩阵是对称的,如下图所示:
有向图的图形示意图以及邻接矩阵表示如下:
通过有向图和无向图的邻接矩阵,总结如下:
(1)无向图的邻接矩阵都是沿对角线对称的
(2)要知道无向图中某个顶点的度,其实就是这个顶点vi在邻接矩阵中第i行或(第i列)的元素之和;
(3)对于有向图,要知道某个顶点的出度,其实就是这个顶点vi在邻接矩阵中第i行的元素之和,如果要知道某个顶点的入度,那就是第i列的元素之和。
2、邻接矩阵实现图的基本存储
具体代码实现:
我们可以利用vector给出存放图的顶点集合和边的集合:
#include<iostream>
using namespace std;
#include<vector>
#if 0
template<class V,class W,bool Isdirect=false>
class Graph
{
public: