一、两个重要概念
1、连通分量:无向图的极大连通子图(该子图是 连通子图,G中再加一个顶点就不连通,再减一条边就不极大);任何连通图的连通分量只有一个,即其本身;非连通图有多个连通分量(非连通图的每一个连通部分)。
2、最小生成树:在一个连通网的所有生成树中,各边的代价之和最小的那棵生成树
二、图的存储结构:
/*图的邻接矩阵的结构表示(多用于稠密图)*/
#define MaxInt 32767 //表示极大值,即∞
#define MaxVNum 100 //表示图中最多可以包含的顶点数
typedef char Vextype; //将顶点的数据类型设为字符型
typedef int Arctype; //将边的权值设为整型
typedef struct
{
Vextype vexs[MaxVNum]; //定点表(用来保存顶点信息的一维数组)
Arctype arcs[MaxVNum][MaxVNum]; //邻接矩阵
int vexnum, arenum; //记录图的顶点数和边数
} AMGraph; //将结构体命名为AMGraph
/*图的邻接表的结构表示(多用于稀疏图)*/
#define MAX_VERTEX_NUM 100//最大顶点个数
#define VertexType int//顶点数据的类型
#define InfoType int//图中弧或者边包含的信息的类型
typedef struct ArcNode
{
int adjvex;//邻接点在数组中的位置下标
struct ArcNode * nextarc;//指向下一个邻接顶点的指针
InfoType * info;//和边相关的信息(eg.权值)
}ArcNode;
typedef struct VNode
{
VertexType data;//顶点的数据域
ArcNode * firstarc;//指向邻接点的指针
}VNode,AdjList[MAX_VERTEX_NUM];//存储各链表头结点的数组,AdjList表示邻接表类型
typedef struct
{
AdjList vertices;//图中顶点的数组
int vexnum,arcnum;//记录图中顶点数和边数
}ALGraph;
三、图的遍历
1.深度优先遍历(DFS):从图中某个顶点v出发,访问此顶点,然后从v的未被访问的邻接点出发深度优先遍历图,直至图中所有的顶点和v有路径相通的顶点都被访问到。(类似于树的先序遍历)
2、广度优先遍历(BFS):首先生成第一层结点,同时检查目标结点是否在所生成的结点中,如果不在,则将所有的第一层结点逐一扩展,得到第二层结点,并检查第二层结点是否包含目标结点,……,对层次为n+1的任一结点进行扩展之前,必须先考虑层次完层次为n的结点的每种可能的状态。因此,对于同一层结点来说,求解问题的价值是相同的,可以按任意顺序来扩展它们。通常采用的原则是先生成的结点先扩展。(类似于树的层次遍历)
四、树的应用
(一)求最小生成树
1、普里姆算法:归并顶点,与边数无关,适用于稠密图
2、克鲁斯卡尔算法:归并边,适用于稀疏图
(二)求最短路径
1.迪杰斯特拉算法(Dijkstra):把图中的顶点集合V分成两组,第一组为已求出最短路径的顶点集合S(初始时S中只有源节点,以后每求得一条最短路径,就将它对应的顶点加入到集合S中,直到全部顶点都加入到S中);第二组是未确定最短路径的顶点集合U。
2.弗洛伊德算法(Floyd):
1,从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。
2,对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短。如果是,更新它。