数据结构与算法学习系列-5-常见的数据结构-图

常见的数据结构-图

概念

图是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为G(V,E),其中G表示一个图,V是图G中顶点的集合,E是图G中边的集合

注意:顶点Vi的度(Degree)是指在图中与Vi相关联的边的条数。

对于有向图来说,有入度(In-degree)和出度(Out-degree)之分,
有向图顶点的度等于该顶点的入度和出度之和

注意:有些图的边或弧具有与它相关的数字,这种与图的边或弧相关的数叫做权
(Weight)

分类与基本实现和特点

无向图

如果图中任意两个顶点之间的边都是无向边(简而言之就是没有方向的边),
则称该图为无向图(Undirected graphs)

有向图

如果图中任意两个顶点之间的边都是有向边(简而言之就是有方向的边),
则称该图为有向图(Directed graphs)

完全图

  • 1.无向完全图
    在无向图中,如果任意两个顶点之间都存在边,则称该图为无向完全图(含有n个顶点的无向完全图有[nx(n-1)]/2条边)
  • 2.有向完全图
    在有向图中,如果任意两个顶点之间都存在方向互为相反的两条弧,则称该图为有向完全图(含有n个顶点的有向完全图有nx(n-1)条边)
  • 3.当一个图接近完全图时,则称它为稠密图(Dense Graph)
    而当一个图含有较少的边时,则称它为稀疏图(Spare Graph)

带权图

如果图中每条边都有一个权重,则该图称为带权图

图的存储

1.邻接矩阵

存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或弧的信息
不足:由于存在n个顶点的图需要n*n个数组元素进行存储,当图为稀疏图时,使用邻接矩阵存储方法将会出现大量0元素,这会造成极大的空间浪费。
这时,可以考虑使用邻接表表示法来存储图中的数据

2.邻接表

邻接表由表头结点和表结点两部分组成,图中每个顶点均对应一个存储在数组中的表头结点。如果这个表头结点所对应的顶点存在邻接结点,则把邻接结点依次存放于表头结点所指向的单向链表中
在这里插入图片描述

图的常见算法

图的遍历:DFS&BFS

DFS:
  • 1.从图中某个顶点Vo出发,首先访问Vo
  • 2.访问结点Vo的第一个邻接点,以这个邻接点Vt作为一个新结点,访问Vt所有邻接点,直到以Vt出发的所有结点都被访问到
  • 回溯到Vo的下一个未被访问过的邻接点,以这个邻接点为新结点
  • 重复上述步骤,直到图中与Vo相通的所有结点都被访问到
  • 3.若此时图中仍有未被访问的结点,则另选图中的一个未被访问的顶点作为起始点。重复深度优先搜索过程,直到图中的所有结点均被访问过
BFS:
  • 1.从图中某个顶点Vo出发,首先访问Vo
  • 2.依次访问Vo的各个未被访问的邻接点
  • 3.依次从上述邻接点出发,访问他们的各个未被访问的邻接点。
    始终保证一点:如果Vi在Vk之前被访问,则Vi的邻接点应在Vk的邻接点之前被访问。重复上述步骤,直到所有顶点都被访问到
  • 4.如果还有顶点未被访问到,则随机选择一个作为起始点
    重复上述过程,直到图中所有顶点都被访问到

提示:为了按照优先访问顶点的次序访问其邻接点,所以需要建立一个优先队列(先进先出)

单源最短路径(迪杰斯特拉Dijkstra 算法)

定一个起点S(源),求出其与所有顶点的最短路径。最短指的是权值之和最小
基本思想:

  • 1.找到所有已知顶点(起始是只有源点S)
  • 2.将所有已知顶点指向的所有未知顶点罗列出来
  • 3.计算源点S到这些未知顶点的distance,找到新distance 最小的顶点X
  • 4.只修改X的distance,并将X设为已知
  • 5.回到第2步,若所有已知顶点的指向结点都已知,则结束

图论-拓扑排序

拓扑排序(Topological Sorting)是一个有向无环图(DAG)的所有顶点的线性序列
该序列必须满足下面两个条件:
1.每个顶点出现且只出现一次
2.若存在一条从顶点A到顶点B的路径,那么在序列中顶点A出现在顶点B的前面

注意:有向无环图才有拓扑排序,非DAG图没有拓扑排序一说
通常,一个有向无环图可以有一个或多个拓扑排序序列

算法思想:
  • 1.从DAG图中选择一个没有前驱(即入度为0)的顶点并输出
  • 2.从图中删除该顶点和所有以它为起点的有向边
  • 3.重复以上步骤,直到当前图中不存在无前驱的顶点

最小生成树

图的生成树包含图的所有结点且仅有n-1边的子图
最小生成树是所有边的代价之和最小的生成树。

求最小生成树有以下两种算法

1.Kruskal算法(加边法)

此算法初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里

算法步骤:

(1)把图中的所有边按代价从小到大排序
(2)把图中的n个顶点看成独立的n棵树组成的森林
(3)按权值从小到大选择边,所选的边连接的两个顶点Ui、Vi,Ui、Vi应属于两棵不同的树,则成为最小生成树的一条边,并将这两棵树合并作为一棵树
(4)重复步骤(3),直到所有顶点都在一棵树内或者有n-1条边为止

2.Prim算法(加点法)

此算法每次迭代选择代价最小的边对应的点,加入到最小生成树中。算法从某一个顶点s开始,逐渐长大直至覆盖整个连通网的所有顶点

算法步骤:

(1)图的所有顶点集合为V;初始令集合u={s},v=V-u
(2)在两个集合u、v能够组成的边中,选择一条代价最小的边(uo,vo),加入到最小生成树中,并把vo并入到集合u中,Vo)
(3)重复上述步骤,直到最小生成树有n-1条边或者n个顶点为止
由于不断向集合u中加点,所以最小代价边必须同步更新;需要建立一个辅助数组closedge,用来维护集合v中每个顶点与集合u中最小代价边信息

常见应用场景

1.微博、微信等社交网络中的好友关系
2.地图导航、交通网络
3. 游戏地图、迷宫
4.计算机网络
5.人际关系推荐系统
6.知识图谱

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lobster爱前端

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

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

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

打赏作者

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

抵扣说明:

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

余额充值