1. 图的概念
图G由顶点集合V(G)和边集合E(G)构成。无向图中的边用圆括号表示,有向图中的边用尖括号表示。
图的基本术语:
端点和邻接点:边(i,j),i和j为端点,互为邻接点;边<i,j>,i为起始端点,j为终止端点,互为邻接点。
度:对于无向图,以i为端点的边数称为顶点的度。对于有向图,分为入度和出度。
完全图:对于无向图,每两个顶点之间都存在着一条边,共
n
(
n
−
1
)
/
2
n(n-1)/2
n(n−1)/2条边。对于有向图,每两个顶点之间都存在方向相反的两条边。
路径长度:路径上经过的边的数目。
简单路径:路径上除开始节点和结束点可以相同外,其余顶点均不相同。
回路和环:路径上的开始点与结束点为同一个顶点。
连通(无向图):i和j之间有路径,则称i和j是连通的。任意两点都连通的图称为连通图。图中的极大连通子图称为连通分量。
强连通(有向图):若i到j和j到i都存在路径,称为强连通图。有向图中的极大强连通子图称为强连通分量。
找强连通分量的方法:首先在图中找有向环;然后扩展该有向环:如果某个顶点到该环中任一顶点有路径,并且该环中任一顶点到这个顶点也有路径,则加入这个顶点。
权:与边相关联的数值。边上带有权的图称为带权图,也称作网。
2. 图的存储结构
存储每个顶点的信息和每条边的信息。有两种主要的存储结构:邻接矩阵和邻接表。
邻接矩阵存储方法:表示顶点之间相邻关系的矩阵。
(1)无向图:
A
[
i
]
[
j
]
=
1
A[i][j]=1
A[i][j]=1,若
(
i
,
j
)
(i,j)
(i,j)属于
E
(
G
)
E(G)
E(G);0,其他。
(2)有向图:
A
[
i
]
[
j
]
=
1
A[i][j]=1
A[i][j]=1,若
<
i
,
j
>
<i,j>
<i,j>属于
E
(
G
)
E(G)
E(G);0,其他。
(3)带权无向图:
A
[
i
]
[
j
]
=
w
i
j
A[i][j]=w_{ij}
A[i][j]=wij,若
i
≠
j
i \not= j
i=j且
(
i
,
j
)
(i,j)
(i,j)属于
E
(
G
)
E(G)
E(G);0:
i
=
j
i=j
i=j;
∞
\infty
∞:其他。
(4)带权有向图:
A
[
i
]
[
j
]
=
w
i
j
A[i][j]=w_{ij}
A[i][j]=wij,若
i
≠
j
i \not= j
i=j且
<
i
,
j
>
<i,j>
<i,j>属于
E
(
G
)
E(G)
E(G);0:
i
=
j
i=j
i=j;
∞
\infty
∞:其他。
邻接矩阵的主要特点:一个图的邻接矩阵表示是唯一的;特别适合稠密图的存储,存储空间为
O
(
n
2
)
O(n^2)
O(n2),与边数无关。
邻接表存储方法
图的邻接表存储方法是一种顺序分配与链式分配相结合的存储方法。
邻接表的特点:表示不唯一(节点顺序可以不同);特别适合稀疏图存储,存储空间为
O
(
n
+
e
)
O(n+e)
O(n+e)。
通常使用指针引用邻接表:引用头节点:G->adjlist[i];引用头节点的指针域:G->adjlist[i].firstarc。
#include <iostream>
using namespace std;
typedef char VertexType;
typedef int InfoType;
#define MaxV 100
//图的邻接矩阵存储类型定义
struct MGraph{//图的定义
int edges[MaxV][MaxV];//邻接矩阵
int n,e;//顶点数和边数
VertexType vexs[MaxV];//存放顶点信息
};
//图的邻接表存储类型定义
struct ArcNode{//边节点类型
int adjVex;//边的终点编号
ArcNode* nextArc;//指向下一条边的指针
InfoType info;//边的信息,如:权
};
struct VNode{//头节点类型
VertexType data;//顶点信息
ArcNode* firstArc;//指向第一条边
};
struct ALGraph{//图邻接表类型
VNode adjlist[MaxV];//邻接表
int n,e;//顶点数和边数
};