数据结构与算法 - 图

 

图的基本概念

图是由顶点集合及顶点间的关系集合组成的一种数据结构。

图G的定义是:       G =(V,E)

即:有顶点,顶点间有连接


基本术语

常用的概念不是很多,掌握基本的几个意思,有个印象即可。

顶点:图中的结点

弧:【有向图】,v为起点,w为终点,<v,w>表示从v到w的一条弧

边 :【无向图】,有<V,W> 就有 <W,V>

权:  可以理解为边的长度

网:带权的图

邻接顶点:

顶点的度指和该顶点相关联的边的数目 , 度 = 入度 +  出度

顶点的入度:该顶点为终点

顶点的出度:该顶点为起点

路径:从一个顶点到另一个顶点的路径

路径的长度:路径上边的数量

回路或环:第一个顶点和最后一个顶点相同的路径

简单路径:路径中序列顶点不重复出现的路径

简单回路:除了第一个顶点和最后一个顶点外,其他顶点不重复出现。

连通:顶点A到顶点B有路径

连通图:任意两个顶点都是连通的

连通分量:无向图中的极大连通子图

强连通图:有向图中,每一对顶点都存在路径。

强连通分量:有向图中的极大强连通子图

连通图的生成树:是连通图的一个极小连通子图,它含有图中全部顶点,但只有足以构成一棵树的n-1条边。


有向图与无向图


性质

 设n表示图中结点数;e表示边或弧的数目。则:

(1)在无向图中,e的取值范围是 0n(n-1)/2;

         在无向图中,如有n(n-1)/2条边,则称为完全图。

(2)在有向图中,e的取值范围是  0n(n-1)

        在有向图中,如有n(n-1)条弧,则称为有向完全图

有很少条边或弧的图称为稀疏图,反之称为稠密图


图的存储结构

邻接表 、  邻接矩阵

1. 邻接矩阵

无向图的邻接矩阵一定是对称矩阵

有向图的邻接矩阵一般是非对称矩阵

带权图及其邻接矩阵

无向图的邻接矩阵

邻接矩阵v1v2v3v4v5

v1

01010
v210101
v301011
v410101
v501110

分析矩阵会发现,这个无向图的邻接矩阵是对称的

其次,每个顶点的度 = 这个顶点所在行(列) 的 1 的个数

特别:完全图中的邻接矩阵中,对角元素全为0 ,其他全1

有向图的邻接矩阵

邻接矩阵v1v2v3v4
v10110
v20000
v30001
v41000

 分析发现,有向图邻接矩阵可能是不对称的。

顶点v1的出度 = 第一行元素之和

顶点v1的入度 = 第一列元素之和

 顶点v1的度 = 第一行元素之和 + 第一列元素之和

(可推广到其他顶点)


2. 邻接表

它是一种顺序存储与链式存储相结合的存储方法,顺序存储部分用来保存图中顶点的信息,链式存储部分用来保存图中边(或弧)的信息

特点

其实是对邻接矩阵法的一种改进

1. 对于n个顶点,e条边的 无向图 ,  会占用n个头结点,以及2e个表结点。即空间占用 (n+2e

        为什么是2e个表结点?因为无向图,A到B,则B也能到A

        如果是稀疏图(e远小于n^2)呢? 则比邻接矩阵(o(n^2))更加节省空间。 

2. 怎么计算无向图的度?单链表中连接结点的个数。

3. 对于n个顶点,e条边的 有向图 ,  会占用n个头结点,以及e个表结点。即空间占用 (n+e

        若是稀疏图,则比邻接矩阵表示法合适。


图的遍历

 从已给的连通图中某一顶点出发,沿着一些边,访遍图中所有的顶点,且使每个顶点仅被访问一次,就叫做图的遍历,它是图的基本运算

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

图的特点:图中可能存在回路,且图的任一顶点都可能与其它顶点相通,在访问完某个顶点之后可能会沿着某些边又回到了曾经访问过的顶点。

如何避免重复访问?

解决思路:可设置一个辅助数组 visited [n ],用来标记每个被访问过的顶点。它的初始状态为0,在图的遍历过程中,一旦某一个顶点i 被访问,就立即改 visited [i]为1,防止它被多次访问。

常用的两种遍历:

1.深度优先遍历DFS

2.广度优先遍历BFS

深度优先遍历

图的深度优先遍历算法是一个递归算法。连通图的深度优先遍历递归算法为:
(1)  访问顶点v并标记顶点v为已访问;
(2)  查找顶点v的第一个邻接顶点w;
(3)  若顶点v的邻接顶点w存在,则继续执行,否则算法结束;
(4)  若顶点w尚未被访问则深度优先搜索递归访问顶点w;
(5)  查找顶点v的相对于w的下一一个邻接顶点w,转到步骤(3)

例题:根据邻接矩阵,从顶点0出发,采用DFS遍历

例题:根据邻接表,从顶点V1出发,采用DFS遍历

深度优先遍历访问序列:
V1 - > V2 ->  v3 ->  V4

如果给出图的存储结构,则访问序列是唯一确定的


广度优先遍历BFS

图的广 度优先遍历算法是一个分层搜索的过程,需要一个队列以保持访问过的顶点的顺序,以便按访问过的顶点的顺序来访问这些顶点的邻接顶点。

广度优先搜索会优先从离起点近的顶点开始搜索

BFS结果
V1→V2→V3→V4→V5→V6→V7→V8

连通图的广度优先遍历算法为:
(1)  访问初始顶点v并标记顶点v为已访问;
(2)  顶点v入队列;
(3)  当队列非空时则继续执行,否则算法结束;
(4)  出队列取得队头顶点u;
(5)  查找顶点u的第-一个邻接顶点w;
(6)  若顶点u的邻接顶点w不存在,则转到步骤(3)否则循环执行,
        (6.1)  若顶点w尚未被访问则访问顶点w并标记顶点w为已访问;
        (6.2)  顶点w入队列;
        (6.3)  查找顶点u的w邻接顶点后的下一个邻接顶点W,转到步骤(6)

如果给出图的存储结构,则访问序列是唯一确定的:

 广度优先遍历访问序列:
V1>V2>V3>V4

例题:已知图的邻接矩阵,根据算法思想,则从顶点0出发按广度优先遍历的结点序列是
 


图的DFS和BFS时间复杂度分析

BFS的复杂度分析
     BFS是一种借用队列来存储的过程,分层查找,优先考虑距离出发点近的点。无论是在邻接表还是邻接矩阵中存储,都需要借助一个辅助队列,v个顶点均需入队,最坏的情况下,空间复杂度O(v)

    邻接表形式存储时,每个顶点均需搜索一次,时间复杂度T1=O(v),从一个顶点开始搜索时,开始搜索,访问未被访问过的节点。最坏的情况下,每个顶点至少访问一次,每条边至少访问1次,这是因为在搜索的过程中,若某结点向下搜索时,其子结点都访问过了,这时候就会回退,故时间复杂度为O(E),算法总的时间复杂度为O(V+E)

邻接矩阵存储方式时,查找每个顶点的邻接点所需时间为O(V),即该节点所在的该行该列。又有n个顶点,故算总的时间复杂度为O( V^2 )

DFS复杂度分析
DFS算法是一一个递归算法,需要借助一个递归工作,故它的空问复杂度为O(V)。

遍历图的过程实质上是对每个顶点查找其邻接点的过程,其耗费的时间取决于所采用结构。

邻接表表示时,查找所有顶点的邻接点所需时间为O(E),访问顶点的邻接点所花时间为O(V),此时,总的时间复杂度为O(V+E)

邻接矩阵表示时,查找每个顶点的邻接点所需时间为O(V),要查找整个矩阵,故总的时间复杂度为O(V^2)。 

 v为图的顶点数,E为边数。


————————————————
版权声明:本文为CSDN博主「Charles_k」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Charles_ke/article/details/82497543


求最短路径问题

1. dijkstra算法求最短路径

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径
它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZuckD

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值