1、图的定义
图(Graph)G由两个集合V和E组成,记为G=(V,E),其中V是顶点的有穷非空集合,E是V中顶点偶对的有穷集合,这些顶点偶对称为边。V(G)和E(G)通常分别表示图G的顶点集合和边集合,E(G)可以为空集。若E(G)为空,则图G只有顶点而没有边。
对于图G,若边集E(G)为有向边的集合,则称该图为有向图;若边集E(G)为无向边的集合,则称该图为无向图。
在有向图中,顶点对<x,y>是有序的,它称为从顶点x到顶点y的一条有向边。因此,<x,y>与<y,x>是不同的两条边。顶点对用尖括号括起来,对<x,y>而言,x是有向边的始点,y是有向边的终点。<x,y>也称作一条弧,则x为弧头,y为弧尾。
在无向图中,顶点对(x,y)是无序的,它称为与顶点x和顶点y相关联的一条边。这条边没有特定的方向,(x,y)与(y,x)是同一条边。为了有别于有向图,无向图的顶点对用一对圆括号括起来。
2、图的基本术语
用n表示图中顶点数目,用e表示边的数目。
1)子图:假设有两个图G=(v,E),和G'=(v',E'),如果v'属于v,且E'属于E,则称G'为G的子图。
2)无向完全图和有向完全图:对于无向图,若具有n(n-1)/2条边,则称为无向完全图。
对于有向图,若具有n(n-1)条弧。则称为有向完全图
3)稀疏图和稠密图:有很少条边或弧(如e<nlog2n)的图称为稀疏图,反之称为稠密图。
4)权和网:在实际应用中,每条边可以标上具有某种含义的数值,该数值称为该边上的
权值。这些权值可以表示从一个顶点到另一个顶点的距离或耗费。这种带权的图通常称为网。
5)邻接点:对于无向图G,如果图的边(v,v')属于E,则称顶点v和v'互为邻接点,即v和v'相
邻接。边(v,v')依附于顶点v和v,或者说边(v,v')与顶点v和v'相关联。
6)度、入度和出度:顶点v的度是指和v相关联的边的数目。对于有向图,顶点v的度分为出度和入度。入度是以顶点v为头的弧的数目,出度是以顶点v为尾的弧的数目。
7)路径和路径长度:在无向图G中从顶点v到顶点v'的路径是一个顶点序列。如果G是有向图,那么路径也是有向的。路径长度是一条路径上经过的边或弧的数目。
8)回路或环:第一个顶点和最后一个顶点相同的路径称为回路或环。
9)简单路径、简单回路或简单环:序列中顶点不重复出现的路径称为简单路径。除了第一个顶点和最后一个顶点之外,其余顶点不重复出现的回路,称为简单回路或简单环。
10)连通、连通图和连通分量:在无向图G中,如果从顶点v到顶点v'有路径,则称v和v'是连通的。如果对于图中任意两个顶点v和v'都是连通的,则称G是连通图。连通分量就是指无向图中极大连通子图。
11)强连通图和强连通分量:在有向图G中,如果对于每一对vi,vj,从vi到vj和从vj到vi都存在路径,则称G是强连通图。有向图中的极大连通子图称作有向图的强连通分量。
3、图的储存结构
1.邻接矩阵表示法
邻接矩阵时表示顶点之间相邻关系的矩阵。设G(V,E)是具有n个顶点的图,则:
A[i][j]=1(<Vi,Vj>或(Vi,Vj)属于E)
A[i][j]=0(其它)
若G是网,则邻接矩阵可以定义为:
A[i][j]=Wij(<Vi,Vj>或(Vi,Vj)属于E)
A[i][j]=无穷(其它)
其中,Wij表示边上的权值;无穷是计算机允许的,大于所有边上的权值的数。
用邻接矩阵表示法表示图,除了一个用于储存邻接矩阵的二维数组外,还需要一个一维数组来储存顶点信息。
//图的邻接矩阵储存表示
#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;
采用邻接矩阵表示法创建无向表
1.输入总顶点数和总边数
2.一次输入点的信息并将其存入顶点表中
3.初始化邻接矩阵,使每个权值初始化为极大值。
4.构造邻接矩阵,依次输入每条边依附的顶点和其权值,确定两个顶点在图中的位置后,使相应边赋予相应的权值,同时使其对称边赋予相同的权值。
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++){ //初始化邻接矩阵,使边的权值均为 MaxInt
for(j=0;j<G.vexnum;j++){
G.arcs[i][j]=MaxInt;
}
}
for(K=0;k<G.arcnum;k++){ //构造邻接矩阵
cin>>v1>>v2>>w; //输入一条边依附的顶点及权值
i=LocatVex(G,v1); //确定v1和v2在G中的位置,即数组下标
j=LocatVex(G,v2);
G.arcs[i][j]=w; //设置边的权值
G.arc[j][i]=G.arcs[i][j];
}
return OK;
}