数据结构——python 006 图

基本概念

逻辑结构:多对多,邻接关系

顶点构成。图可以只有点,没有边

图G(Graph)由两个集合V(Vertex)和E(Edge)组成,记为G=(V,E)。
V是顶点的有限集合,记为V(G)。
E是连接V中两个不同顶点(顶点对)的边的有限集合,记为E(G)。

无向图

每条边都是无方向的

有向图

每条边都是有方向的

完全图——最稠密的图

任意两个点都有边相连

稀疏图

有很少边或弧的图

稠密图

有较多边或弧的图,接近于完全图

边或弧带权的图

邻接

有边/弧相连的两个两个顶点之间的关系

无向图()

有向图 <>

顶点的度

与该顶点相关联的边的数目(无向图)

该顶点入度和出度的和为(有向图)该顶点顶点的度

路径

连续的边构成的顶点序列

路径长度

路径上边或弧的数目/权值之和

回路(环)

第一个顶点和最后一个顶点相同

简单路径

除了起点和终点的顶点可以相同外,其他顶点都不重复出现

简单回路(环)

除路径起点和终点相同外,其余顶点均不相同的路径

“无向图”连通图(“有向图”强连通图)

在无向图(有向图)中,对任意两个顶点,都存在这两个顶点之间的路径,则称这个图是连通图(强连通图)

连通分量

无向图G的极大连通子图称为G的连通分量

(极大连通子图:该子图是G连通子图,将G的任何不在该子图的顶点加入,子图不再连通)

有限图G的极大连通子图称为G的强连通分量

极小连通子图

该子图是G的连通子图,在该子图中删除任何一条边,子图不再连通

生成树

包含无向图G的所有顶点的极小连通子图

生成森林

对非连通图,由各个连通分量的生成树的集合

存储结构

邻接矩阵

邻接矩阵是表示顶点之间邻接关系的矩阵

借助二维数组来表示元素间的的关系(数组表示法/邻接矩阵)

特点
  • 图的邻接矩阵表示是唯一的。
  • 对于含有n个顶点的图,采用邻接矩阵存储时,无论是有向图还是无向图,也无论边的数目是多少,其存储空间均为O(n2),所以邻接矩阵适合于存储边数较多的稠密图
  • 无向图的邻接矩阵一定是一个对称矩阵。因此在顶点个数n很大时可以采用对称矩阵的压缩存储方法减少存储空间。
  • 对于无向图,邻接矩阵的第i行(或第i列)非零元素(或非∞元素)的个数正好是顶点i的度。
  • 对于有向图,邻接矩阵的第i行(或第i列)非零元素(或非∞元素)的个数正好是顶点i的出度(或入度)。
  • 用邻接矩阵方法存储图,确定任意两个顶点之间是否有边相连的时间为O(1)

有向图只画出度

邻接表——链式

将每个顶点i(0≤i≤n-1)的所有出边构成一个列表。
假设顶点i的出边有m条,即<i,j1>,<i,j2>,…,<i,jm>(权值分别为wi,j1,wi,j2,…,wi,jm)。

顶点

按编号顺序将顶点数据存储在一维数组中

关联同一顶点的边(以顶点为尾的弧)

用线性链表存储

特点
  • 邻接表表示不唯一。
  • 于有n个顶点和e条边的无向图,其邻接表有n个表头结点和2e个边结点;对于有n个顶点和e条边的有向图,其邻接表有n个表头结点和e个边结点。显然,对于边数目较少的稀疏图,邻接表比邻接矩阵要节省空间。
  • 对于无向图,顶点i(0≤i≤n-1)对应的单链表的边结点个数正好是顶点i的度。
  • 对于有向图,顶点i(0≤i≤n-1)对应的单链表的边结点个数仅仅是顶点i的出度。顶点i的入度是邻接表中所有adjvex值为i的边结点个数。
  • 用邻接表存储图时,确定任意两个顶点之间是否有边相连的时间为O(m)(m为最大顶点出度,m<n)。

遍历

从给定图中任意指定的顶点(称为初始点)出发,按照某种搜索方法沿着图的边访问图中的所有顶点,使每个顶点仅被访问一次,这个过程称为图遍历。

为了避免同一个顶点被重复访问,必须记住访问过的顶点。为此,可设置一个访问标志数组visited,初始时所有元素置为0,当顶点i访问过时,该数组元素visited[i]置为1。

实质:找每个顶点邻接点的过程

深度优先遍历(DFS)
广度优先遍历(BFS)

生成树和最小生成树

概念

生成树:所有顶点均由边连接在一起,但不存在回路的图

最小生成树:一个带权连通图G(假定每条边上的权值均大于零)可能有多棵生成树.
每棵生成树中所有边上的权值之和可能不同.
其中边上的权值之和最小的生成树称为图的最小生成树

由深度优先遍历得到的生成树称为深度优先生成树。
由广度优先遍历得到的生成树称为广度优先生成树。
无论哪种生成树,都是由相应遍历中首次搜索的边构成的。

普里姆(Prim)算法(选择点)

一个一个找,找最小的

(1)初始化U={v}。以v到其他顶点的所有边为候选边。
(2)重复以下步骤n-1次,使得其他n-1个顶点被加入到U中:
① 从候选边中挑选权值最小的边加入TE(所有候选边一定是连接两个顶点集U和V-U的边),设该边在V-U中的顶点是k,将顶点k加入U中。
② 考察当前V-U中的所有顶点j,修改候选边:若(k,j)的权值小于原来和顶点j关联的候选边,则用(k,j)取代后者作为候选边。

时间复杂度:O(n2

适用:稠密图

克鲁斯卡尔(Kruskal)算法(选择边)

先把全部顶点都摆出来,从最小的权值开始选,注意不能形成环

(1)置U的初值等于V(即包含有G中的全部顶点),TE的初值为空集(即图T中每一个顶点都构成一个分量)。
(2)将图G中的边按权值从小到大的顺序依次选取:若选取的边未使生成树T形成回路,则加入TE;否则舍弃,直到TE中包含n-1条边为止。

时间复杂度:O(e)
e为边数

适用:稀疏图

最小生成树不一定唯一

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值