图是一种比线性表、树更为复杂的数据结构。图是一种非线性的数据结构,图中的数据元素之间的关系是多对多的关系。
#1.图的定义
图是由数据元素集合V与边的集合E构成的。在图中,数据元素通常称为顶点。其中,顶点集合V不能为空,边表示顶点之间的关系。
若
<
x
,
y
>
∈
E
<x,y> \in E
<x,y>∈E则
<
x
,
y
>
<x,y>
<x,y>表示从顶点x到顶点y存在一条弧,x称为弧尾或起始点,y称为弧头或终端点。这样的图称为有向图。
若
<
x
,
y
>
∈
E
<x,y> \in E
<x,y>∈E且有
<
y
,
x
>
∈
E
<y,x> \in E
<y,x>∈E,即E是对称的,则用无序对(x,y)代替有序对
<
x
,
y
>
<x,y>
<x,y>和
<
y
,
x
>
<y,x>
<y,x>,表示x和y之间的存在一条边,这样的图称为无向图。
图的形式化定义为G=(V,E),其中, V = { x ∣ x ∈ 数据元素的集合 } V=\{x|x \in数据元素的集合 \} V={x∣x∈数据元素的集合}, E = { < x , y > ∣ P a t h ( x , y ) ∧ ( x ∈ V , y ∈ V ) } E=\{<x,y>|Path(x,y) \wedge (x \in V,y \in V)\} E={<x,y>∣Path(x,y)∧(x∈V,y∈V)}。Path(x,y)表示 < x , y > <x,y> <x,y>的意义或信息。
注:有向图的边称为弧,无向图的边称为边。图中顶点的顺序可以是任意的,任何一个顶点都可以作为图的第一个顶点。
#2.图的相关概念
- 邻接点
对于无向图G=(V,E),若边
(
v
i
,
v
j
)
∈
E
(v_i,v_j)\in E
(vi,vj)∈E,则称
v
i
v_i
vi和
v
j
v_j
vj互为邻接点,即
v
i
v_i
vi和
v
j
v_j
vj相邻接。边
(
v
i
,
v
j
)
(v_i,v_j)
(vi,vj)依附于顶点
v
i
v_i
vi和
v
j
v_j
vj,或者说边
(
v
i
,
v
j
)
(v_i,v_j)
(vi,vj)与顶点
v
i
v_i
vi、
v
j
v_j
vj相关联。对于有向图G=(V,A),若弧
<
x
,
y
>
∈
A
<x,y>\in A
<x,y>∈A,则称顶点
v
i
v_i
vi邻接到顶点
v
j
v_j
vj,顶点
v
j
v_j
vj邻接自顶点
v
i
v_i
vi,弧
<
x
,
y
>
<x,y>
<x,y>和顶点
v
i
v_i
vi、
v
j
v_j
vj相关联。
无向图
G
2
G_2
G2的边的集合为
E
=
{
(
a
,
b
)
,
(
a
,
c
)
,
(
a
,
d
)
,
(
b
,
c
)
,
(
c
,
d
)
}
E=\{(a,b),(a,c),(a,d),(b,c),(c,d)\}
E={(a,b),(a,c),(a,d),(b,c),(c,d)},顶点a和b互为邻接点,边(a,b)依附于顶点a和b。顶点c和d互为邻接点,边(c,d)依附于顶点c和d。有向图
G
1
G_1
G1的弧的集合为
A
=
{
<
a
,
b
>
,
<
a
,
d
>
,
<
b
,
c
>
,
<
c
,
a
>
,
<
c
,
b
>
,
<
d
,
c
>
}
A=\{<a,b>,<a,d>,<b,c>,<c,a>,<c,b>,<d,c>\}
A={<a,b>,<a,d>,<b,c>,<c,a>,<c,b>,<d,c>},顶点a邻接到顶点b,弧
<
a
,
b
>
<a,b>
<a,b>与顶点a和b相关联。顶点c邻接自顶点d,弧
<
d
,
c
>
<d,c>
<d,c>与顶点d和c相关联。
- 顶点的度
对于无向图,顶点v的度是指与v相关联的边的数目,记作TD(v)。对于有向图,以顶点v为弧头的数目称为顶点v的入度,记作ID(v)。以顶点v为弧尾的数目称为v的出度,记作OD(v)。顶点v的度为TD(v)=ID(v)+OD(v)。
若图的顶点个数为n,边数和弧数为e,顶点
v
i
v_i
vi的度记作
T
D
(
v
i
)
TD(v_i)
TD(vi),则顶点的度与弧或者边数满足关系
e
=
1
2
∑
i
=
1
n
T
D
(
v
i
)
e=\frac {1}{2} \sum_{i=1}^n TD(v_i)
e=21∑i=1nTD(vi) 。
- 路径
无向图G中,从顶点v到顶点v’的路径是从v出发,经过一系列的顶点序列到达顶点v’。如果G是有向图,则路径也是有向的,路径的长度是路径上弧或者边的数目。第一个顶点和最后一个顶点相同的路径称为回路或环。序列中顶点不重复出现的路径称为简单回路或简单环。
- 子图
假设存在两个图 G = { V , E } G=\{V,E\} G={V,E}和 G ′ = { V ′ , E ′ } G'=\{V',E'\} G′={V′,E′},若G’的顶点和关系都是V的子集,即有 V ′ ⊆ V V' \subseteq V V′⊆V, E ′ ⊆ E E' \subseteq E E′⊆E,则$G’ 为 为 为G$的子图。
- 连通图和强连通图
对于无向图G,如果从顶点 v i v_i vi到顶点 v j v_j vj存在路径,则称 v i v_i vi到 v j v_j vj是连通的。如果对于图中任意两个顶点 v i v_i vi、 v j ∈ V v_j \in V vj∈V, v i v_i vi和$v_j $都是连通的,则称G是连通图。无向图中的极大连通子图称为连通分量。
对于有向图G,如果对每一对顶点 v i v_i vi到 v j v_j vj,且 v i ≠ v j v_i \neq v_j vi=vj,从 v i v_i vi到 v j v_j vj和从 v j v_j vj到 v i v_i vi都存在路径,则G为强连通图。有向图中的极大强连通子图称为有向图的强连通分量。
- 完全图
若图的顶点数目是n,图的边(弧)的数目是e。若不存在顶点到自身的边或弧,即若存在 < v i , v j > <v_i,v_j> <vi,vj>,则有 v i ≠ v j v_i \neq v_j vi=vj。对于无向图,边数e的取值范围为0n(n-1)/2。将具有n(n-1)/2条边的无向图称为**完全图**或无向完全图。对于有向图,弧数e的取值范围是0n(n-1)/2。具有n(n-1)/2条弧的有向图称为有向完全图。
- 稀疏图和稠密图
具有 e < n l o g n e<nlogn e<nlogn条弧或边的图称为稀疏图,反之称为稠密图。
- 生成树
一个连通图的生成树是一个极小连通子图,它含有图的全部顶点,但只有足以构成一棵树的n-1条边。如果在该生成树中添加一条边,则一定会在图中出现一个环。一棵具有n个顶点的生成树仅有n-1条边,如果少于n-1条边,在该图是非连通的;多于n-1条边,则一定有环出现。反过来,具有n-1条边的图不一定能构成生成树。一个图的生成树不一定是唯一的。
- 网
在图的边或弧上,有时标有与它们相关的数,这种与图的边或弧相关的数称作权。这些权可以表示从一个顶点到另一个顶点的距离或代价。这种带权的图称为网。
#3.图的抽象数据类型
##数据对象集合
图的数据对象为图的各个顶点和边的集合。图中的顶点是没有先后次序的。图分为有向图和无向图,图中结点之间的关系用弧或者边表示,通过弧或边相连的顶点相邻接或相关联。
图中顶点之间是多对多的关系,即任何一个顶点可以有与之邻接或关联的顶点。
##基本操作集合
(1)CreateGraph(&G):创建图。
(2)DestroyGraph(&T):销毁图。
(3)LocateVertex(G,v):返回顶点v在图中的位置。
(4)GetVertex(G,i):返回图G中序号i对应的值。
(5)FirstAdjVertex(G,v):返回v的第一个邻接顶点。
(6)NextAdjVertex(G,v,w):返回v的下一个邻接顶点。
(7)InsertVertex(&G,v):图的顶点插入操作。
(8)DeleteVertex(&G,v):图的顶点删除操作。
(9)InsertArc(&G,v,w):图的弧插入操作。
(10)DeleteArc(&G,v,w):图的弧删除操作。
(11)DFSTraverseGraph(G):图的深度优先遍历操作。
(12)BFSTraverseGraph(G):图的广度优先遍历操作。