本博客主要介绍图的基本概念、图的存储结构和有关图的一些常用算法
1) 图的定义和术语
2) 图的各种存储结构
3) 图的深度优先搜索(DFS)和广度优先搜索(BFS)遍历算法
图的定义
图G由两个集合V和E组成,记为 G = ( V,E )
V是顶点的有穷非空集合,E是V中顶点偶对的有穷集
这些顶点偶对称为边。通常V(G)和E(G)分别称为图的顶点集合和边集合
注: E(G)可以为空集
图的数据结构的形式化定义
G = ( V,E )
其中 V = { x | x dataobject }
E ={VR}
VR={<x,y>| p(x,y) ( x,y V ) }
VR是两顶点间的关系的集合,即边的集合
有向图: 对一个图G,若边集E(G)为有向边的集合,则称该图为有向图
G1=(V,E)
V={v1, v2, v3, v4}
E={<v1, v2>, <v1, v3>, <v3, v4>, <v4, v1>}
其中<x, y>表示从x到y的一条弧(arc),A为弧集合,x为弧尾(tail),y为弧头(head)
无向图: 对一个图G,若边集E(G)为无向边的集合,则称该图为无向图
G2=(V,E)
V={v1, v2, v3, v4, v5}
E={(v1, v2), (v1, v3), (v2, v3), (v3, v4), (v2,v5), (v3,v5)}
其中,(x, y)表示x与y之间的一条连线,称为边(edge)
顶点与顶点之间用边做联系,边带→称为有向图,不带→称为无向图
权值:描述两个顶点之间边的关系,①→②之间的距离
根据边有没有权值,把图分为有权图和无权图
有 4 种不同的组合:有向带权图,有向无权图,无向带权图,无向无权图
边和顶点关系
设n为顶点数,e为边或弧的条数
对无向图有:0 ≤ e ≤ n ( n - 1 ) / 2
有向图有:0 ≤ e ≤ n ( n - 1 )
证明:对有向图,每个顶点至多有n-1条边与其它的n-1个顶点相连,则n个顶点至多有 n ( n - 1 ) 条边。但对无向图,每条边连接2个顶点,故最多为 n ( n - 1 ) / 2
端点和邻接点
在一个无向图中,若存在一条边<vi,vj>, 则称vi,vj为该边的两个端点,并称它们互为邻接点:用一条边连接的两个顶点
起点和终点
在一个有向图中,若存在一条边<vi,vj>, 则称该边是顶点vi的一条出边,是vj的一条入边,称vi是起始端点(或起点),称vj是终止端点(或终点),并称它们互为邻接点
度 图中每个顶点的度是以该顶点为一端点的边的数目。记为 D(V)
入度和出度 对于有向图,入度为以该顶点为终点的边的数目,出度为以该顶点为起点的边的数目
子图 设有两个图G=(V,E) G’=(V’,E’)中,若V’是V的子集, E’是E的子集,则称G’是G子图,图中的某一块
简单图 对不含多重边和自环的图
对于③顶点有 3 条边,可以连接其他顶点,度为 3
① 和 ② 有多重边,① 为环状,不属于简单图
完全图 边达到最大的图
无向完全图:具有 n ( n - 1 ) / 2 条边的简单图称为无向完全图
有向完全图:具有 n ( n - 1 ) 条边的有向图。
稀疏图: 边或弧很少的图。
稠密图: 边或弧很多的图。
权:与图的边或弧相关的数。
网:边或弧上带有权值的图。
路径:非空有限点、弧交替序列, W=v0,a1,v1, … , ak,vk 使得 i =1,2,… k,弧ai的头vi , 尾为vi-1
路径长度:路径上边或弧的数目
简单路径:除首尾两点外,其他各点都不相同的路径称为简单路径
回路:无重复边的闭路径
环:闭的简单路径,称为环
连通图:任何两点都有路径的图。
无向图:若图中任意两个顶点vi,vj都是连通的,则称该图是连通图(vi< >vj)
有向图:若图中任意两个顶点vi,vj,都存在从vi到vj 和从 vj到vi的路径,则称该有向图为强连通图 (vi< >vj)
图的两种存储结构
矩阵法:二维数组的操作
邻接表法
矩阵法:一般用于描述有向带权图:
把图存在内存中去,根据内存中用 矩阵法 | 邻接表法 存的数据,可以把整个图还原出来
矩阵法把每个顶点当做矩阵的表头
5 个顶点最多有 5 * 5 条边,构建一个 5 * 5 的矩阵
用户输入边的信息,决定矩阵数组如何存储,要输入起点和终点,起点确定行数,终点确定列数
用什么东西表示不填充都可以,需要和连通的状态产生差异性
邻接表法:描述无向无权图:数组链表
首先把顶点放到一个数组中去,用一个数组把 A,B,C,D,E 5 个顶点存储起来
如果 A 到 B 连通,就把 A 的邻接顶点 B 的序号存到以 A 为头节点的链表中去,以 A 创建一个链表,A中有一个指针表示整个链表
注意:链表中存的不是顶点,存的是顶点的序号,B 顶点在序号为①的位置,所以把 1 存到链表中去,A 到 D 连通,把D顶点的序号 3 也存到链表中去
链表用什么方式插入都可以
连通的顶点都放在以当前顶点为头节点的链表中去即可