图状结构简称图,是另一种非线性结构,它比树形结构更复杂。树形结构中 的结点是一对多的关系,结点间具有明显的层次和分支关系。每一层的结点可以 和下一层的多个结点相关,但只能和上一层的一个结点相关。而图中的顶点(把 图中的数据元素称为顶点)是多对多的关系,即顶点间的关系是任意的,图中任 意两个顶点之间都可能相关。也就是说,图的顶点之间无明显的层次关系,这种 关系在现实世界中大量存在。因此,图的应用相当广泛,在自然科学、社会科学 和人文科学等许多领域都有着非常广泛的应用
6.1. 图的基本概念
6.1.1 图的定义
图(Graph)是由非空的顶点(Vertex)集合和描述顶点之间的关系——边 (Edge)或弧(Arc)的集合组成。其形式化定义为: G=(V,E) V={vi|vi∈某个数据元素集合} E={(vi,vj)|vi,vj∈V∧P(vi,vj)}或E={<vi,vj>|vi,vj∈V∧P(vi,vj)} 其中,G 表示图,V 是顶点的集合,E 是边或弧的集合。在集合 E 中,P(vi,vj) 表示顶点 vi 和顶点 vj 之间有边或弧相连。图 6.1 给出了图的示例
在图 6.1(a)中,V={v1,v2,v3,v4,v5} E={(v1,v2),(v1,v3),(v2,v4),(v2,v5),(v3,v4),(v4,v5)}
在图 6.1(b)中,V={v1,v2,v3,v4,v5} E={<v1,v2>,<v1,v3>,<v2,v3>,<v2,v5)><v3,v4>,<v4,v1>,<v4,v5>}。
6.1.2 图的基本术语
图的基本术语有以下 14 种:
- 无向图:在一个图中,如果任意两个顶点vi和vj构成的偶对(vi,vj)∈E是无序的, 即顶点之间的连线没有方向,则该图称为无向图(Undirected Graph)。图 6.1(a)是一个无向图。
- 有向图:在一个图中,如果任意两个顶点vi和vj构成的偶对<vi,vj>∈E是有序 的,即顶点之间的连线有方向,则该图称为有向图(Directed Graph)。图 6.1(b)是 一个有向图。
- 、边、弧、弧头、弧尾:无向图中两个顶点之间的连线称为边(Edge),边用顶 点的无序偶对(vi,vj)表示,称顶点vi和顶点vj互为邻接点(Adjacency Point),(vi,vj) 边依附与顶点vi和顶点vj。有向图中两个顶点之间的连线称为弧(Arc),弧用顶点 的有序偶对<vi,vj>表示,有序偶对的第一个结点vi称为始点(或弧尾),在图中不 带箭头的一端;有序偶对的第二个结点vj称为终点(或弧头),在图中带箭头的 一端。
- 无向完全图:在一个无向图中,如果任意两个顶点之间都有边相连,则称该 图为无向完全图(Undirected Complete Graph)。可以证明,在一个含有 n 个顶点的 无向完全图中,有 n(n-1)/2 条边。
- 有向完全图:在一个有向图中,如果任意两个顶点之间都有弧相连,则称该 图为有向完全图(Directed Complete Graph)。可以证明,在一个含有 n 个顶点的有 向完全图中,有 n(n-1)条弧.
- 顶点的度、入度、出度:在无向图中,顶点 v 的度(Degree)是指依附于顶 点 v 的边数,通常记为 TD(v)。在有向图中,顶点的度等于顶点的入度(In Degree) 与顶点的出度之和。顶点v的入度是指以该顶点v为弧头的弧的数目,记为ID(v); 顶点 v 的出度(Out Degree)是指以该顶点 v 为弧尾的弧的数目,记为 OD(v)。所 以,顶点 v 的度 TD(v)= ID(v)+ OD(v)。例如,在无向图 6.1(a)中有: TD(v1)=2 TD(v2)=3 TD(v3)=2 TD(v4)=3 TD(v5)=2 在有向图 6.1(b)中有: ID(v1)=2 OD(v1)=1 TD(v1)=3 ID(v2)=1 OD(v2)=2 TD(v2)=3 ID(v3)=2 OD(v3)=1 TD(v3)=3 ID(v4)=1 OD(v4)=2 TD(v4)=3 ID(v5)=2 OD(v5)=0 TD(v5)=2
- 权、网:有些图的边(或弧)附带有一些数据信息,这些数据信息称为边(或 弧)的权(Weight)。在实际问题中,权可以表示某种含义。比如,在一个地方 的交通图中,边上的权值表示该条线路的长度或等级。在一个工程进度图中,弧 上的权值可以表示从前一个工程到后一个工程所需要的时间或其它代价等。边 (或弧)上带权的图称为网或网络(Network)。图 6.2 是带权图的示例图
- 子图:设有两个图 G1=(V1,E1),G2=(V2,E2),如果 V1 是 V2 子集, E1 也是 E2 的子集,则称图 G1 是 G2 的子图(Subgraph)。图 6.3 是子图的示例图。
- 、路径、路径长度:在无向图G中,若存在一个顶点序列Vp,Vi1,Vi2,…,Vim, Vq,使得(Vp,Vi1),(Vi1,Vi2),…,(Vim,Vq)均属于E(G)。则称顶点Vp到 Vq存在一条路径(Path)。若G为有向图,则路径也是有向的。它由E(G)中的弧 <Vp,Vi1>,<Vi1,Vi2>,…,<Vim,Vq>组成。路径长度(Path Length)定义为路 径上边或弧的数目。在图 6.2(a)中,从顶点A到顶点B存在 4 条路径,长度分别为 1、2、2、4。在图 6.2(b)中,从顶点 1 到顶点 7 存在 2 条路径,长度分别为 2 和 3.
- 简单路径、回路、简单回路:若一条路径上顶点不重复出现,则称此路径为 简单路径(Simple Path)。第一个顶点和后一个顶点相同的路径称为回路(Cycle) 或环。除第一个顶点和后一个顶点相同其余顶点都不重复的回路称为简单回路 (Simple Cycle),或者简单环。
- 连通、连通图、连通分量:在无向图中,若两个顶点之间有路径,则称这两 个顶点是连通的(Connect)。如果无向图 G 中任意两个顶点之间都是连通的,则 称图 G 是连通图(Connected Graph)。连通分量(Connected Compenent)是无向图 G的极大连通子图。极大连通子图是一个图的连通子图,该子图不是该图的其它连 通子图的子图。图 6.3 是连通图,图的连通分量的示例见图 6.4 所示。图 6.4(a) 中的图 G 有两个连通分量。
- 强连通图、强连通分量:在有向图中,若图中任意两个顶点之间都存在从一 个顶点到另一个顶点的路径,则称该有向图是强连通图(Strongly Connected Graph)。有向图的极大强连通子图称为强连通分量(Strongly Connected Component)。极大强连通子图是一个有向图的强连通子图,该子图不是该图的其 它强连通子图的子图。图 6.5 是强连通图,图 6.6 是强连通分量的示例图。图 6.6(a) 中的有向图 G 有两个强连通分量。
- 、生成树:所谓连通图 G 的生成树(Spanning Tree)是指 G 的包含其全部顶点 的一个极小连通子图。所谓极小连通子图是指在包含所有顶点并且保证连通的前 提下包含原图中少的边。一棵具有 n 个顶点的连通图 G 的生成树有且仅有 n-1 条边,如果少一条边就不是连通图,如果多一条边就一定有环。但是,有 n-1 条 边的图不一定是生成树。图 6.7 就是图 6.3(a)的一棵生成树。
- 生成森林:在非连通图中,由每个连通分量都可得到一个极小连通子图,即 一棵生成树。这些连通分量的生成树就组成了一个非连通图的生成森林 (Spanning Forest)。
6.1.3 图的基本操作
图的基本操作用一个接口来表示,为表示图的基本操作,同时给出了顶点类 的实现。由于顶点只保存自身信息,所以顶点类 Node<T>很简单,里面只有一 个字段 data
顶点的类 Node<T>的实现如下所示
public class Node<T>
{
//数据域
private T data;
//构造器
public Node(T v)
{
data = v;
}
//数据域属性
public T Data
{
get
{
return data;
}
set
{
data = value;
}
}
}
图的接口IGraph<T>的定义如下所示。
public interface IGraph<T>
{
//获取顶点数
int GetNumOfVertex();
//获取边或弧的数目
int GetNumOfEdge();
//在两个顶点之间添加权为v的边或弧
void SetEdge(PipeNodeVo2D v1, PipeNodeVo2D v2, float v);
//删除两个顶点之间的边或弧
void DelEdge(PipeNodeVo2D v1, PipeNodeVo2D v2);
//判断两个顶点之间是否有边或弧
bool IsEdge(PipeNodeVo2D v1, PipeNodeVo2D v2);
}
下面对图的基本操作进行说明:
1、GetNumOfVertex() 初始条件:图存在; 操作结果:返回图中的顶点数。
2、GetNumOfEdge() 初始条件:图存在; 操作结果:返回图中的边或弧的数目。
3、SetEdge(Node<T> v1, Node<T> v2, int v) 初始条件:图存在,顶点 v1 和 v2 是图的两个顶点; 操作结果:在顶点 v1 和 v2 之间添加一条边或弧并设边或弧的值为 v。
4、DelEdge(Node<T> v1, Node<T> v2) 初始条件:图存在,顶点 v1 和 v2 是图的两个顶点并且 v1 和 v2 之间有一 条边或弧; 操作结果:删除顶点 v1 和 v2 之间的边或弧。
5、IsEdge(Node<T> v1, Node<T> v2) 初始条件:图存在,顶点 v1 和 v2 是图的两个顶点; 操作结果:如果 v1 和 v2 之间有一条边或弧,返回 true,否则返回 false。