kruskal算法(最小生成树) python实现

本文介绍了Kruskal算法的基本思路,该算法通过按边的权重从小到大排序,并使用并查集避免形成环路来构建最小生成树。接着,提供了一段Python代码实现这一算法。
摘要由CSDN通过智能技术生成

kruskal(克鲁斯卡尔)的思路很直观,边按权值从小到大排序,然后从小到大选不会构成回路的边,构成生成树。(选两点不在同一个连通分量里面的边)

构建并查集,用并查集判断是否构成回路(是否在同一个分量里面)(两个连通分量如果根结点相同,两点连接就会构成回路)

python代码:

def find(x, pres):
    """
    查找x的最上级(首级)
    :param x: 要查找的数
    :param pres: 每个元素的首级
    :return: 根结点(元素的首领结点)
    """
    root, p = x, x  # root:根节点, p:指针

    # 找根节点
    while root != pres[root]:
        root = pres[root]

    # 路径压缩,把每个经过的结点的上一级设为root(直接设为首级)
    while p != pres[p]:
        p, pres[p] = pres[p], root
    return root


def join(x, y, pres, ranks):
    """
    合并两个元素(合并两个集合)
    :param x: 第一个元素
    :param y: 第二个元素
    :param pres: 每个元素的上一级
    :param ranks: 每个元素作为根节点时的秩(树的深度)
    :return: None
    """
    h1, h2 = find(x, pre
以下是使用Kruskal算法实现最小生成树Python代码示例: ```python # 定义边的类 class Edge: def __init__(self, src, dest, weight): self.src = src self.dest = dest self.weight = weight # 定义并查集类 class UnionFind: def __init__(self, vertices): self.parent = {} self.rank = {} for v in vertices: self.parent[v] = v self.rank[v] = 0 def find(self, v): if self.parent[v] != v: self.parent[v] = self.find(self.parent[v]) return self.parent[v] def union(self, v1, v2): root1 = self.find(v1) root2 = self.find(v2) if self.rank[root1] < self.rank[root2]: self.parent[root1] = root2 elif self.rank[root1] > self.rank[root2]: self.parent[root2] = root1 else: self.parent[root2] = root1 self.rank[root1] += 1 # 定义最小生成树函数 def kruskal(graph): result = [] # 将图的边按权重排序 graph.sort(key=lambda x: x.weight) # 获取图中的所有顶点 vertices = set() for edge in graph: vertices.add(edge.src) vertices.add(edge.dest) # 创建并查集 uf = UnionFind(vertices) # 遍历图的边 for edge in graph: root1 = uf.find(edge.src) root2 = uf.find(edge.dest) # 如果两个顶点的根节点不同,则将边加入最小生成树中 if root1 != root2: result.append(edge) uf.union(root1, root2) return result # 示例用法 graph = [ Edge('A', 'B', 4), Edge('A', 'H', 8), Edge('B', 'C', 8), Edge('B', 'H', 11), Edge('C', 'D', 7), Edge('C', 'F', 4), Edge('C', 'I', 2), Edge('D', 'E', 9), Edge('D', 'F', 14), Edge('E', 'F', 10), Edge('F', 'G', 2), Edge('G', 'H', 1), Edge('G', 'I', 6), Edge('H', 'I', 7) ] minimum_spanning_tree = kruskal(graph) for edge in minimum_spanning_tree: print(f"{edge.src} - {edge.dest}: {edge.weight}") ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值