图的小结

对于图这种数据结构,可以从五个维度来理解:表示方法,搜索算法,最小生成树,最短路径,最大流。

一、表示方法

邻接表和邻接矩阵

通常采用邻接表(Adj)的方法,因为这种方法表示稀疏图(|E|远小于|V|2的图)比较紧凑,所需的存储空间为O(v+E),不足之处在于要确定某一边(u ,v)是否存在只能在顶点u的邻接表Adj[u]中来搜索v。

二、搜索算法

广度优先搜索和深度优先搜索

广度优先搜索:假设输入用邻接表来表示,对于每个顶点u∈V,其彩色变量存储于变量color[u]中,u的父母变量存于变量π[u]中,如果没有父母或者尚未发现则π[u]=NIL,源点和顶点u之间的距离存于变量d[u]中,算法用一个先进先出的队列Q来管理所有的灰色顶点。此算法可以解决百度地图中两点“最小换乘”的问题。

输出s到v上最短路径所有顶点的时候采用递归的方法,当s=v的时候递归终止。

深度优先搜索:也是同多对顶点着色来表示顶点的状态,深度优先搜索可以从多个源顶点开始搜索,从而可以生成一个深度优先搜索森林。广度优先搜索通常用于从某个顶点开始寻找最短路径,深度优先搜索通常作为另一个算法的一个子程序。深度优先搜索的最基本特征是他的先子辈图形成了一个森林,另一个重要的特性是发现和完成时间具有括号结构,这个可以用来实现拓扑排序,经拓扑排序的顶点以与其完成时刻相反的顺序出现,算法实现的时候用一个链表,当深度优先搜索一个顶点完成的时候(变黑),就把这个顶点插入到链表的前面。

拓扑排序:对有向无回路图G进行拓扑排序后,结果为该图所有顶点的一个线性序列,满足如果G包含边(u,v)则在该序列中,u就出现在v的前面(如果是有回路的,就不可能存在这样的线性序列),有向无回路图经常用于说明事件发生的先后次序。

三、最小生成树

Kruskal(克鲁斯卡尔)算法和Prim算法

Kruskal和Prim算法都是用普通的二叉堆,都很容易达到O(ElgV)的运行时间,通过采用斐波那契堆,Prim算法的运行时间可以减少到O(E+VlgV),如果V远小于E的话,这将是对算法的较大改进。两个算法都是贪心算法。

Kruskal:该算法找出森林中连接任意两棵树的所有边中,具有最小权值的的边(u,v)作为安全边,并把它添加到正在生长的森林中。

Prim:Prim算法的执行非常类似与寻找图的最短路径的Dijkstra算法。集合中的的边总是形成但棵树,直到该树覆盖了V中的所有顶点。

四、最短路径

有四个个基本形式:单源最短路径问题,单终点最短路径问题,单对顶点最短路径问题,每对顶点最短路径问题。

单源是找出某个给定的源点到每个顶点的最短路径,单终点是从每个顶点到指定的终点的的最短路径(可以把图中的每条边反向,从而转化成单源最短路径问题),单对顶点最短路径问题是找出给定的两个顶点的最短路径,目前还没有比单源算法更快的算法来解决这一问题。以上三类都可以用单源最短路径来解决,还有一种求每对顶点间的最短路径问题,虽然将每个顶点作为源点,运行一次单源算法就可以解决这一问题,但通常可以更快的解决这一问题。

基本算法:Bellman-Ford和Dijkstra(迪杰斯特拉

这两个算法都会重复的对边进行松弛,松弛是改变路径和前驱的唯一方式,算法的区别在于对每条边进行的松弛操作次数,以及对边执行松弛操作的次序有所不同。在Dijkstra算法中对每条边执行一次松弛操作,在Bellman-Ford算法中,对每条边要执行多次松弛操作。

Bellman-Ford:该算法能在一般的情况(存在负权边的情况)下解决单源最短路径问题),对图运行Bellman-Ford算法后可以返回一个布尔值,表明图中是否存在着一个从源点可达的负的回路。算法的运行时间为O(VE)。

一种特殊情况:有向无回路图,安顶点的拓扑序列对某加权dag图(有向无回路图)G=(V,E) 的边进行松弛后,就可以在O(V+E)时间内计算单源最短路径。也可以求最长路径,把边的权值取负值,运行dag-shortest-path求的路径即为最长路径,可以应用在求某项工作的最晚完成时间。

Dijkstra:该算法解决了有向图上待权的单源最短路径问题,但要求所有的边的权值非负。算法的运行时间依赖于最小优先队列的实现方式。二叉最小堆实现最小优先队列的时候为O((E+V)lgV),斐波那契堆来实现最小优先队列时候,可以将运行时间提升到O(VlgV+E)。

Dijkstra算法和广度优先搜索算法Prim算法有类似之处。和广度优先算法的相似在于,前者的集合S相当于后者的黑色顶点集合,正如集合S中的顶点有着最终的最短路径的权值,广度优先搜索的黑色顶点也有着正确的广度优先距离。Dijsktra算法和Prim 算法相似之处在于,两种算法均采用最小优先队列,来找出给点集合(Dijsktra算法中集合S以及Prim算法中的生长树)以外“最轻”的顶点,然后把该点加入到集合中,并相应的调整该集合以外的剩余顶点的权。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值