一、图的定义和基本术语
-
图:G=(V,E) V:顶点(数据元素)的有穷非空集合;E:边的有穷集合
-
无向图:每条边都是无方向的
-
有向图:每条边都是有方向的
-
完全图:任意两个点都有一条边相连
-
稀疏图:有很少边或弧的图
-
稠密图:有较多边或弧的图
-
网:边/弧带权的图
-
邻接:有边/弧相连的两个顶点之间的关系
存在(vi,vj),则称vi和vj互为邻接点
存在<vi,vj>,则称vi邻接到vj,vj邻接于vi
-
关联(依附):边/弧与顶点之间的关系
存在(vi,vj)/<vi,vj>,则称该边/弧关联与vi和vj
-
顶点的度:与该点相关联的边的数目,记为TD(v)
在有向图中,顶点的度等于该顶点的入度与出度之和
-
路径:接续的边构成的顶点序列
-
路径长度:路径上边或弧的数目/权值之和
-
回路(环):第一个顶点和最后一个顶点相同的路径
-
简单路径:除路径起点和终点可以相同外,其余顶点均不相同的路径
-
简单回路(简单环):除路径起点和终点相同外,其余顶点均不相同的路径
-
连通图(强连通图):在无(有)向图G=(V,{E})中,若对任何两个顶点v、u都存在从v到u的路径,则称G是连通图(强连通图)
-
连通分量(强连通分量):无向图的极大连通子图称为连通分量;有向图的极大强连通子图,称为强连通分量
-
极小连通子图:该子图是G的连通子图,在该子图中删除任何一条边后子图不在连通
-
生成树:包含无向图G所有顶点的极小连通子图
-
生成森林:对非连通图,有各个连通分量的生成树的集合
二、图的类型定义
-
GreateGraph(&G,V,VR)
- 初始条件:V是图的顶点集,VR是图中弧的集合
- 操作结果:按V和VR的定义构造图G
-
DFSTraverse(G)
- 初始条件:图G存在
- 操作结果:对图进行深度优先遍历
-
BFSTraverse(G)
- 初始条件:图G存在
- 操作结果:对图进行广度优先遍历
三、图的存储结构
1、邻接矩阵
- 数组(邻接矩阵)表示法
- 建立一个顶点表(记录各个顶点信息)和一个邻接矩阵(表示各个顶点之间关系)
- 设图A=(V,E)有n个顶点,则顶点表Vexs[n]
- 图的邻接矩阵是一个二维数组A.arcs[n] [n]
- 邻接矩阵的存储表示:用两个数组分别存储顶点表和邻接矩阵
#define MaxInt 32767
#define MVNum 100
typedef char VerTexType;
typedef int ArcType;
typedef struct
{
VerTexType vexs[MVNum];
ArcType arcs[MVNum][MVNum];
int vexnum,arcnum;
}AMGraph;
- 算法:采用邻接矩阵表示法创建无向网
Status CreateUDN(AMGraph &G)
{
cin>>G.vexnum>>G.arcnum;
for(i=0;i<G.vexnum;++i)
cin>>G.vexs[i];
for(i=0;i<G.vexnum;++i)
for(j=0;j<G.vexnum;++j)
G.arcs[i][j]=MaxInt;
for(k=0;k<G.arcnum;++k)//构造邻接矩阵
{
cin>>v1>>v2>>w;//输入一条边所依附的顶点及边的权值
i=LocateVex(G,v1);
j=LocateVex(G,v2);//确定v1和v2在G中的位置
G.arcs[i][j]=w;//边<v1,v2>的权值置为w
G.arcs[j][i]=G.arcs[i][j];//置<v1,v2>的对称边<v2,v1>的权值为w
}
return OK;
}
- 算法:在图中查找顶点
int LocateVex(AMGraph G,VertexType u)
{
int i;
for(i=0;i<G.vexnum;++i)
if(u==G.vexs[i])
return i;
return -1;
}
- 优点:
- 直观、简单、好理解
- 方便检查任意一对顶点间是否存在边
- 方便找任一顶点的所有“邻接点”(有边直接相连的顶点)
- 方便计算任一顶点的“度”
- 缺点:
- 不便于增加和删除顶点
- 浪费空间——存稀疏图有大量无效元素
2、邻接表表示法
- 顶点:按编号顺序将顶点数据存储在一维数组中
- 关联同一顶点的边(以顶点为尾的弧):用线性链表存储
- 特点:
- 邻接表不唯一
- 若无向图中有n个顶点、e条边、则其邻接表需n个头结点和2e个表结点。适宜存储稀疏图
- 无向图中顶点vi的度为第i个单链表中的结点数
- 顶点结构
typedef struct VNode
{
VerTexType data;//顶点信息
ArcNode *firstarc;//指向第一条依附该顶点的边的指针
}VNode,AdjList[MVNum];//AdjList表示邻接表类型
- 边的结点结构
#define MVNum 100//最大顶点数
typedef struct ArcNode//边结点
{
int adjvex;//该边所指向的顶点的位置
struct ArcNode *nextarc;//指向下一条边的指针
OtherInfo info;//和边相关的信息
}ArcNode;
- 图的结构定义
typedef struct
{
AdjList vertices;
int vexnum,arcnum;
}ALGraph;
- 采用邻接表表示法创建无向网
Status CreateUDG(ALGraph &G)
{
cin>>G.vexnum>>G.arcnum;
for(i=0;i<G.vexnum;++i)
{
cin>>G.vertices[i].data;
G.vertices[i].firstarc=NULL;
}
for(k=0;k<G.arcnum;++k)
{
cin>>v1>>v2;
i=LocateVex(G,v1);
j=LocateVex(G,v2);
p1=new ArcNode;
p1->adjvex=j;
p1->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p1;
p2=new ArcNode;
p2->adjvex=i;
p2->nextarc=G.vertices[j].firstarc;
G.vertices[j].firstarc=p2;
}
return OK;
}