图: 由顶点的有穷非空集合和顶点之间边的集合组成
图的基本概念:
在图型数据结构中,数据被称为顶点,数据之间的关系被称为边
在图中不允许出现没有点,但可以没有边
G(V,E) V表示顶点的集合, E表示边的集合
图的种类:
无向图:顶点与顶点之间的边没有方向,这种边称为无向边,边用无向序偶对表示(v,v1)
V={A,B,C,D} E={(A,B),(B,C),(C,D),(D,A),(A,C)}
在无向图中,如果任意两个顶点之间都存在边,这种图称为无向完全图
有向图:若顶点之间有方向,这种边称为有向边,也叫弧
边用有序偶对<v,v1>,表示从v到v1的一条弧,v叫作弧尾,v1叫作弧头
注意:若不存在顶点到自身的边,也不存在重复出现的边,这种图叫简单图,数据结构中讨论的都是简单图
在有向图中,如果任意两个顶点之间存在方向相反的两条弧,这种图叫作有向完全图
图中有很少边或弧的图叫作稀疏图,反之叫作稠密图
如果图中的边或弧附有相关的数据,数据叫作权,这种图也叫作网(带权图)
如果G(V,E)和G1(V1,E1),存在,那么G1是G的子图
顶点与边的关系:
顶点的度:指的是顶点相关联的边或弧的条目数
有向图又分为入度和出度
入度:其它顶点到该顶点的弧的条目数。
出度:从该点出发到其它顶点的弧的条目数
路径:从一个顶点到另一个顶点的顶点序列,路径长度指的是路径上的边或弧的条目数
回路或环:第一个顶点和最后一个顶点相同的路径
简单路径:序列中顶点不重复出现的路径
简单回路或简单环:除了第一个顶点和最后一个顶点之外,其余顶点都不重复出现的路径
连通图相关术语:
在无向图中,在顶点v到v1之间有路径,则称v到v1之间是连通的,如果任意两个顶点都是连通的(两点之间可以有其它点),那么这种图称为连通图 。
无向图中的极大连通子图(再添加一个顶点或一条边,该子图就不连通了)称为连通分量:
1.必须是子图
2.子图必须是连通的
3.连通子图含有极大的顶点数
有向图强连通分量 :在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点 强连通 (strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个 强连通图 。有向图的极大强连通子图,称为强连通分量
图的存储结构:
图的存储主要是两个方面:顶点,边
邻接矩阵:利用一个矩阵表示各顶点之间的邻接关系
一个一维数组(顶点)和一个二维数组(边、弧)组成
二维数组 i,i 的位置都是0,如果是无向图,根据 i,i (左上到右下的对角线为轴)数组对称
优点:
1.非常容易判定两点之间是否有边
2.非常容易计算任意顶的入度和出度
3.非常容易统计邻接点
缺点:如果存储稀疏图,会浪费存储空间
邻接表:由顶点表(顺序存储),边表(链式存储)组成
顶点表 边表
存储顶点,下一个邻接点地址/下标 顶点下标 | 下一个邻接点地址
A -> [ 1] -> [ 3] -> NULL
B [ 2] ->NULL
C [ 4] -> [ 3] ->NULL
D [ ] ->
E [ ] ->
优点:
1.节省存储空间
2.非常容易计算出度
缺点:不方便计算入度
十字链表:由于邻接表不能同时兼顾入度和出度,因此修改邻接表的边表结构,使它既存储入度也存储出度,这种表叫作十字链表
邻接多重表:由于遍历表时需要一些删除边的操作,而邻接表在删除边时非常麻烦,因此设计出邻接多重表
边集数组:由两个一维数组构成,一个存储顶点的信息,另一个(结构体的数组,成员begin,end,weight)存储边的信息,(它的每个数据元素都由一条边的起点到终点的下标和权组成)
这种存储结构更侧重于边的相关操作(路径、路径长度、最短路径),而统计顶点的度,需要扫描整个数组,效率不高
图的总结:
1.根据图论中树的公式:顶点数 - 1 = 边数
2.无向图:
无向完全图: 最多n*(n-1)/2条边,
顶点表结点: n个顶点就有n个表结点
边表节点: n*(n-1)个
表结点: n + n*(n-1)=n^2个
3. n个顶点的连通图至少有n-1条边(树);
4. n个顶点的简单图(完全图)至少有n*(n-1)/2条边。
5.邻接矩阵与邻接表的比较
- 存储表示: 邻接矩阵:唯一,邻接表:不唯一
- 空间复杂度:O(n^2) ,适用稠密图; O(n+e),稀疏图
- 求顶点的度: 按有向图和无向图的计算方法进行;有向图中,邻接矩阵比邻接表更方便
- 判断图中的边:判断矩阵中元素中的值是否为0;需要搜索链表,最坏的情况O(n)
- 求边的数目:检测整个邻接矩阵,需要O(n^2);统计邻接表中结点个数总和需要O(n+e)