图的结构:
一些图的概念:
**图:**图G是由顶点集V和边集E组成。G=(V,E) V={v1,v2…} E={(u,v) …} |E|为边的条数。
图的阶:V={v1,v2…} |V|为顶点的个数也叫做图的阶。
**注:**线性表可以为空表,树可以为空树,但图不可以为空图,顶点集一定非空,边集可以为空。
**有向图:**边是顶点的有序对E={<1,2>…}
**无向图:**边是顶点的无序对E={(1,2)}
**完全图:**在无向图中,若任意两个顶点之间都存在边,则称该图为:无向完全图。共有n(n-1)/2边。
在有向图中,若任意两个顶点之间都存在方向相反的两条弧,则称该图为:有向完全图,共有n(n-1)条边。
**子图:**两个图G={V,E}, G’={V’,E’},若V’是V的子集,E’是E的子集。则称G’为G的子图。
(并非 V 和 E 的任何子集都能构成 G 的子图,因为这样的子集可能不是图)
生成子图: 若有满足V’=V的子图G’ ,则为G的生成子图。
连通: 在无向图中,若从顶点v到顶点u有路径存在,则称v到u是连通的。
**连通图:**在无向图中,若图G任意两个顶点都是连通的,则称G为连通图。
**连通分量:**无向图中的极大连通子图
(极大表示该连通图包括连通顶点所有的边,是与极小连通子图相对的概念)
强连通:在有向图中,若从顶点 v 到顶点 w 和从顶点 w 到顶点 v 之间都有路径。
**强连通图:**在有向图中,若图中任何一对顶点都是强连通的,则称此图为强连通图。
**强连通图:**有向图中中,极大强连通子图称为有向图的强连通分量
**生成树:**连通图的生成树是包含图中全部顶点的一个极小连通子图。n个顶点的生成树有n-1条边。
**生成森林:**在非连通图中,连通分量的生成树构成非连通图的生成森林。
顶点的度:对于无向图,顶点 v 的度是指依附于该顶点的边的条数,记为TD(v)。
对于有向图,顶点 v 的度是指其出度于入度之和。记为TD(v)= OD(v)+ ID(v)
**顶点的出度与入度:**出度是以顶点 v 为起点的有向边的数目,记为 OD(v)。入度是以顶点 v 为终点的有向边的数目,记为 ID(v)
**边的权和网:**在一个图中,每条边都可以标上具有含义的数值,该数值称为该边的权值。这种边上带有权值的图称为带权图,也称网。
稠密图,稀疏图: 一般当图 G 满足IEl<IVl*loglVI时,可以将 G 看成是稀疏图。
**路径:**顶点 Vp到顶点 Vq之间的一条路径是指一条 Vp到Vq的顶点序列。
**路径长度:**路径上边的数目称为路径长度。
简单路径: 在路径序列中,顶点不重复出现的路径称为简单路径。
**简单回路:**除第一个顶点或最后一个顶点之外,其他顶点不重复出现的回路叫做简单回路。
…
图的存储:
邻接矩阵法:(图的线性存储)
一个一维数组储存顶点的信息,一个二维数组存储边的信息。这个二维矩阵称为邻接矩阵。
、
typedef struct
{
vertextype vex[maxvertexnum]; //顶点表
edgetype edge[maxvertexnum][maxvertexnum];//邻接矩阵
int vexnum,arcnum; //顶点数目,边数。
}
对于无向图:
①邻接矩阵为对称矩阵(并且唯一)。
②对于无向图 ,邻接矩阵的第 i 行(或第 i 列)非零元素(或非∞元素)的个数正好是第 i个顶点的度 TD(vi)。
对于有向图:
①邻接矩阵的第 i 行 (或第 i 列] )非零元素(或非∞元素)的个数正好是第 i个顶点的出度OD(vi) (或入度 ID(vi))。
设图G的邻接矩阵为 A, A^n的元素 A^n[i][j]等于由顶点 i 到顶点 j 的长度为 n 的路径的数目。
**优点:**很容易就能确定任意两个顶点是否有边相连。
**缺点:**确定图中有多少条边,则需要按行按列对每个元素进行检测,花费时间多。
**适用性:**适用于稠密图的存储表示。
邻接表法:(图的链式存储)
对图的顶点采取顺序存储方式,对顶点的边采取链式存储方式。
顶点表结点由顶点域(data)和指向第一条邻接边的指针(firstare)构成,
边表(邻接表) 结点由邻接点域(adjvex)和指向下一条邻接边的指针域(nextarc)构成。
typedef struct Arcnode //定义边表结点的数据结构
{
int adjvex; //该条弧指向的下一个结点的位置
struct Arcnode*next; //指向下一条弧的指针
}Arcnode;
typedef struct Vnode//定义顶点表的数据结构
{
vertextype data; //顶点信息
Arcnode*first; //指向第一条依附于该顶点的弧的指针
}Vnode;Adjlist[MAXVERTEXNUM];
typedef struct //邻接表表示法
{
Adjlist vertices; //定义邻接表
int vexnum,arcnum; //顶点数,弧数。
}ALGragh;
对于无向图:
①所需的存储空间为 O(IVl+2IEI);
②顶点的度等于边表的结点数。
对于有向图:
①所需的存储空间为O(IVl+IEI);
②顶点的出度等于边表的节点数。但入度则需要遍历全部邻接表。
优点:对于一个顶点,很快能找到它的所有邻边。
缺点:对于两个顶点之间是否存在边相连,则需在一顶点的邻接表中查找,时间效率低。
适用性:适用于稀疏图。
十字链表:
是有向图的一种链式存储方式。
顶点用顺序存储,弧用链式存储。
顶点结点: data 域存放顶点相关的数据信息,firstin 和 firstout 两个 域分别指向以该顶点为弧头或弧尾的第一个弧结点。
弧结点: 其中尾域(tailvex)和头域(headvex)分别指示弧尾和弧头这两个顶点 在图中的位置,
链域 hlink 指向弧头相同的下一条弧,链域 tlink 指向弧尾相同的下一条弧,info 域指向该弧的相关信息。
typedef struct Arcnode //定义边表的数据结构
{
int tailvex,headvex; //该弧的头尾节点
struct Arcnode *hlink,*tlink; //指向弧头相同或弧尾相同的结点
}Arcnode;
typedef struct Vnode //定义顶点表的数据结构
{
vertextype data; //顶点信息
Arcnode* firstin,firstout; //指向第一条出弧和入弧
}Vnode;
typedef struct
{
Vnode xlist[MAXVERTEXNUM]; //定义十字链表
int vexnum,arcnum; //顶点数和边数
}GLGragh;
在十字链表中可以很快的找到顶点的出度和入度。
邻接多重表:
是无向图的一种链式存储方式。
弧结点: mark 为标志域用以标记该条边是否被搜索过; ivex 和 jvex 为该边依附的两个顶点在图中的位置;
ilink 指向下一条依附于顶点 ivex 的边;jlink 指向下一条依附于顶点jvex 的边;info 为指向和边相关的各种信息的指针域。
typedef struct Arcnode //定义边表的数据结构
{
bool mark; //访问标识符
int ivex, jvex; //指向该弧的两个结点
struct Arcnode*ilink,*jlink; //分别指向两个顶点的下一条边。
}Arcnode;
typedef struct Vnode //定义顶点表的数据结构
{
vertextype data; //顶点信息
Arcnode *firstedge; //指向第一条依附于该顶点的弧
}Vnode;
typedef struct
{
Vnode adjmulist[MAXVERTEXNUM]; //定义邻接多重表
int vexnum,arcnum; //顶点数,边数。
}AMLGraph;