39 图论算法

图的表示:
一种简单的方法:用二维数组,成为邻接矩阵表示法,对于每条边(u,v),置A[u][v]等于true,否则是false。如果边有权,可使其值等于权。但这种方法很浪费空间,尤其是对稀松的图。
对于稀松图,可以使用邻接表,对于每一个顶点,用一个表存放所有邻接的顶点。
两种实现方式:1.使用一个映射,在这个映射下,关键字是那些顶点而他们的值就是邻接表。2.把邻接表作为vetex类数据成员。

拓扑排序
对有向无圈图的一种排序
对每顶点计算它的入度,然后将入度为0的顶点放入一个初始为空的队列中。当队列不为空时,删除一个顶点,并将与此顶点相邻的所有顶点的入度减1,只要一个顶点的入度降为0,就把该顶点放入队列中,此时,拓扑排序就是顶点出队的顺序。

图/树—深度优先搜索(DFS)
DFS相对于BFS只是把queue换成stack
1.把起始点放入栈中
2.重复下述步骤,直到栈为空为止

  • 从栈中访问栈顶的点
  • 找到与此点邻接的且尚未遍历的点,进行标记,然后全部放入栈中
  • 如果此点没有尚未遍历的邻接点,则从此栈中弹出

判断有向图是否有圈
第一种方法:.拓扑排序(变形)
算法描述:将所有入度为0的顶点放入队列
2.每次从队列中弹出一个顶点V,(即访问到该顶点,count++),直到队列为空
3.遍历所有与V相连的顶点,将相连的顶点入度减1(删边)
4.若某个相邻的顶点入度为0,则将其放入队列,返回第二步
5.若count==N,即所有顶点均访问到,说明排序完成,否则说明顶点入度不为0,没有放入队列中,即该图有圈。
第二种方法:DFS法
稍微修改下DFS,利用递归
Vis[u]=0 代表还没访问
Vis[u]=-1 代表还在访问中
Vis[u]=1 代表访问完全
出现1,表示有圈

无向图判断是否有环
如果存在回路,则必存在一个子图是一个回路,此环路中所有顶点的度大于等于2
算法 第一步:.删除所有度<=1的顶点及其相关的边,并将另外与这些也相关的其他顶点的度减1。
第二步:将度数变为1的顶点放入队列,并从该队列中取出一个顶点重复步骤一
如果最后还有未删除顶点,则存在环。
算法分析:由于有m条边,n个顶点,如果m>=n,根据图论可知,存在环路。如果m<n 按上述算法,每删除一个度为0的顶点,最多n次,或每删除一个度为1的顶点,同时删除一条边,操作一次,最多m次,故算法复杂度O(n)

无权最短路径

详见《数据结构与算法分析》253页

问题描述:对应一个无权图,找出从某个顶点到其他所有顶点的最短路径。
算法理解表:记录每个点:是否已被访问过;距离起始点路径长度;上游节点
算法:将每个点赋初值d=INFINITY,know=false. 起始点d=0 ,d从小到大遍历每一个点,将已遍历的点know设为true,记录上游点,在上游点的d的基础上增1。

有权最短路径
Dijkstra算法
将每个点赋初值d=INFINITY,know=false. 起始点d=0 ,d从小到大遍历每一个点,并改变其下游节点的d的值,将已遍历的点know设为true,记录上游点,在上游点的d的基础上增加权重的大小,如果一个点又要被被另一个上游点给重新赋值时,判断新值是否小于旧值,选择较小的给其重新赋值。

最小生成树
在无向图中找出一棵最小生成树,即在联通网的所有生成树中,所有边的代价之和最小的生成树成为最小生成树。
其边的条数为|V|-1,它是包含所有顶点的最小的树
prim算法
算法的每一阶段通过选择边(u, v)使得(u, v)的值是所有u在树上但v不在树上的边的值中的最小值而找出一个新的顶点并把它添加到树上
Kruskal算法
连续的按照最小的权选择边,并且当所选的边不产生圈时就把它作为所取定的边

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值