数据结构-图
图
-
G = (V,E)
V:顶点(数据元素)的有穷非空集合;
E:边的有穷集合。
-
图的每条边有方向(明确的指向的)被称为有向图
反之,被称为无向图。
-
完全图:任意两个点都有一条边相连
-
无向完全图:n个顶点,n(n-1)/2条边。
-
有向完全图:n个顶点,n(n-1)条边。
-
稀疏图:有很少边或弧的图。
-
稠密图:有较多边或弧的图。
-
网:边/弧带权的图。
-
邻接:有边/弧相连的两个顶点之间的关系。
存在(vi,vj),则称vi和vj互为邻接点;
存在<vi,vj>,则称vi邻接到vj,vj邻接于vi
-
关联(依附):边/弧与顶点之间的关系。
存在(vi,vj)/<vi,vj>,则称改变/弧关联于vi和vj
-
顶点的度:与该顶点相关联的边的数目,记为TD(v)。
-
在有向图中,顶点的度等于该顶点的入度与出度之和。
顶点v的入度:是以v为终点的有向边的条数,记作ID(v)。
顶点V的出度:是以v为始点的有向边的条数,记作OD(v)。
-
路径:接续的边构成的顶点序列。
-
路径长度:路径上边或弧的数目/权值之和。
-
回路(环):第一个顶点和最后一个顶点相同的路径。
-
简单路径:除路径起点和终点可以相同外,其余顶点均不相同的路径。
-
简单回路(简单环):除路径起点和终点相同外,其余顶点均不相同的路径。
-
连通图(强连通图)
在无(有)向图G=(V,{E})中,若对任何两个顶点v,u都存在从v到u的路径,则称G是连通图(强连通图)。
-
权与网
图中边或弧所具有的相关数称为权。表明从一个顶点到另一个顶点的距离或耗费。
带权的图称作网。
-
子图
设有两个图G=(V,{E})、G1=(V1,{E1}),若V1包含于V,E1包含于E,则称G1是G的子图。
-
连通分量(强连通分量)
- 无向图G的极大连通子图称为G的连通分量。
- 极大连通子图的意思是:该子图是G连通子图,将G的任何不在该子图中的顶点加入,子图不再连通。
- 有向图G的极大强连通子图称为G的强连通分量。
-
极小连通子图:该子图是G的连通子图,在该子图中删除任何一条边,该子图不再连通。
-
生成树:包含无向图G所有顶点的极小连通子图
-
生成森林:对非连通图,由各个连通分量的生成树的集合。
六度空间理论
你和任何一个陌生人之间所间隔的人不会超过六个。
图的类型定义
- 数据对象:具有相同特性的数据元素的集合,称为顶点集。
- 数据关系:顶点,弧(边),权。
重要操作
-
构造图
CreateGraph(&G,V,VR)
初始条件:V是图的顶点集,VR是图中弧的集合
操作结果:按V和VR的定义构造图G。
-
遍历
-
DFSTraverse(G)
初始条件:图G存在。
操作结果:对图进行深度优先遍历。
-
BFSTraverse(G)
初始条件:图G存在。
操作结果:对图进行广度优先遍历。
-
图的存储结构
-
多对多关系
图没有顺序存储结构,但是可以借助二维数组来表示元素间的关系。
-
数组表示法(邻接矩阵)
-
链式存储结构:邻接表,邻接多重表,十字链表
-
-
邻接矩阵:
- 建立一个顶点表(记录各个顶点信息)和一个邻接矩阵(表示各个顶点之间关系)。
- 无向图的邻接矩阵是对称的;
- 对于无向图而言,顶点i的度 = 第i行(列)中1的个数。
- 无向完全图的邻接矩阵中,对角元素为0,其余为1.
- 对于有向图而言,
- 第i行含义:以结点vi为尾的弧(即出度边)
- 第i列含义:以结点vi为头的弧(即入度边)
- 有向图的邻接矩阵可能是不对称的。
- 顶点的出度=第i行元素之和
- 顶点的入度=第i列元素之和
-
网(即有权图)的邻接矩阵表示法
- 定义:
- 如果这两个顶点之间有弧或者边,那么在这两个顶点之间位置关系的位置上记录他们之间的权。
- 如果没有边或者弧,就记录一个无穷大
- 定义:
邻接矩阵的存储表示:用两个数组分别存储顶点表和邻接矩阵
#define MVNum 100 //最大顶点数
#define Maxint 32767 //表示极大值,即无穷大
typedef char VerTexType; //设顶点的数据类型为字符型
typedef int ArcType; //假设边的权值类型为整型
typedef struct{
VerTexType vexs[MVNum];//顶点表
ArcType arcs[MVNum][MVNum];//邻接矩阵
int vexnum,arcnum;//图的当前点数和边数
}AMGraph; //Adjacency Matrix Graph
-
算法思想(无向网)
- 输入总顶点数和总边数
- 依次输入点的信息存入顶点表中
- 初始化邻接矩阵,使每个权值初始化为极大值。
- 构造邻接矩阵
Status CreateUDN(AMGraph &G) { cin >> G.vexnum >> G.arcnum;//输入总顶点数,总边数 for(i = 0;i<G.vexnum;++i) { cin >> G.vexs[i]; } for(<