(python)图算法:拓扑排序算法+kruskal算法+prim算法+Dijkstra算法实现

补充图的几个算法:拓扑排序算法 、kruskal算法、prim算法和Dijkstra算法实现。

一.拓扑排序算法

拓扑排序算法适用于无环的、有入度为0的图。
再说一下该算法的一个应用场景,在实现工程代码时,各个代码文件之间存在依赖关系,所以需要进行编译顺序排序。此时就可以使用拓扑排序算法实现编译顺序确定。

方法:
找到入度为0的点,然后记入result,随后擦除该点的影响(点和边),然后继续找到入度为0的点记入result,周而复始。

代码:
为方便起见,使用了我的上一篇博客中构建的图:(python)数据结构图的描述实现+其他描述方式的转换示例
示例的图如下:
示例图的拓扑排序应为1 2 3。
在这里插入图片描述

def TopologySorted(graph):
    '''
    拓扑排序实现
    :param graph:
    :return:
    '''
    Indegree = {
   } #入度字典
    ZeroIndegree = [] #入度为0的点集
    result = [] #结果列表
    for node in graph.nodes.values():
        Indegree[node] = node.indegree
        if node.indegree==0:ZeroIndegree.append(node)
    #拓扑排序,添加result
    while len(ZeroIndegree)!=0:
        node = ZeroIndegree.pop(0) #先进先出
        result.append(node)
        for i_n in node.nexts:
            Indegree[i_n] -= 1 #擦除对直接邻居的影响,入度-1
            if Indegree[i_n]==0:ZeroIndegree.append(i_n)
    return result

for i in TopologySorted(graph):
    print(i.value,end=' ') #output: 1 2 3

二.kruskal算法

kruskal算法适用于无向图,用于生成最小生成树。

方法:
从边的角度出发,在不形成环的前提下依次选择最小边。

代码中实现环的判断的方法:
最开始所有点各自成独立的集合,随着对边的考虑,一条边的起点和终点集合将进行合并,最后是否形成环的判定标准就是看某个点是否在某个集合中——也就是并查集结构(做查询和合并速度为常数)。

代码:
注意,以下代码实现了一种类似并查集的结构,但是没有并查集快。代码是我按照左神和k算法思路实现的,肯定还有更加优雅的方式~~btw我还是想记录自己的代码哈哈。
假设示例图为:
在这里插入图片描述
示例图的最小生成树应为:
在这里插入图片描述
使用前面链接中的方法创建图:

#创建图
graph_test = [[1,2,5], #表示从1到2的边,权重为5
              [2,1,5], #表示从2到1的边,权重为5
              [2,3,7], #表示从2到3的边,权重为7
              [3,2,7], #表示从3到2的边,权重为7
              [1,3,4], #表示从1到3的边,权重为4
              [3,1,4]] #表示从3到1的边,权重为4
graph = CreateGraph(graph_test)

K算法:

class MineDSU(object):
    '''
    实现并查集的功能(非并查集)
    '''
    def __init__(self,nodes:Node):
        self.total = [] #集合列表
        for node in nodes.values(): #每个点各自成独立的集合
            self.total.append(set([node]))
    def isSame(self,fromnode:Node,tonode:Node)->bool:
        '''
        判断fromnode和tonode是否是同一个集合
        :param fromnode:
        :param tonode:
        :return:
 
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值