当前位置:首页python > 正文

Python 算法:最小生成树(Kruskal 算法)

作者:野牛程序员:2025-12-22 11:28:23python阅读 2018
Python 算法:最小生成树(Kruskal 算法)
# /*
# Python 算法:最小生成树(Kruskal 算法)
# --------------------------------------------------------
# 原理概要:
# Kruskal 属于贪心算法,通过“从小到大选边”的方式生成最小生成树。
#
# 基本步骤:
# 1) 将图中所有边按权值从小到大排序;
# 2) 依次取最小边,如果加入后不产生环,则加入 MST;
# 3) 使用并查集(Union-Find)判断是否成环;
# 4) 直到 MST 包含 (顶点数 - 1) 条边。
#
# 适合场景:
# - 稀疏图效果优于 Prim 的矩阵实现
# - 边较少但权值不均的情况效率更高
# */

# --------------------------------------------------------
# 并查集(Union-Find)实现
class UnionFind:
    def __init__(self, size):
        self.parent = list(range(size))
        self.rank = [0] * size

    def find(self, x):
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])   # 路径压缩
        return self.parent[x]

    def union(self, x, y):
        rootX = self.find(x)
        rootY = self.find(y)

        if rootX != rootY:
            # 按秩合并
            if self.rank[rootX] < self.rank[rootY]:
                self.parent[rootX] = rootY
            elif self.rank[rootX] > self.rank[rootY]:
                self.parent[rootY] = rootX
            else:
                self.parent[rootY] = rootX
                self.rank[rootX] += 1
            return True
        return False

# --------------------------------------------------------
# Kruskal 主算法
def kruskal_mst(vertices, edges):
    """
    vertices: 顶点数量
    edges: 边列表 (u, v, weight)
    """
    # 1) 边按权值排序
    edges = sorted(edges, key=lambda x: x[2])

    uf = UnionFind(vertices)
    mst = []

    # 2) 从小到大选边
    for u, v, w in edges:
        if uf.union(u, v):     # 能加入 MST(无环)
            mst.append((u, v, w))

        if len(mst) == vertices - 1:
            break

    return mst

# --------------------------------------------------------
# 示例图:边列表 (u, v, weight)
edges = [
    (0, 1, 2),
    (0, 3, 6),
    (1, 2, 3),
    (1, 3, 8),
    (1, 4, 5),
    (2, 4, 7),
    (3, 4, 9)
]

vertices = 5

# 执行 Kruskal
mst = kruskal_mst(vertices, edges)

# 显示结果
print("最小生成树边列表 (u, v, weight):")
for e in mst:
    print(e)

# --------------------------------------------------------
# 输出示例(顺序可能不同,但结构一致) (u, v, weight):
# (0, 1, 2)
# (1, 2, 3)
# (1, 4, 5)
# (0, 3, 6)
#
# Kruskal 要点总结:
# - 利用“排序 + 并查集”实现;
# - 最适合边稀疏的图;
# - 时间复杂度 O(E log E);
# - 保证不会形成环;
# */


野牛程序员教少儿编程与信息学奥赛-微信|电话:15892516892
野牛程序员教少儿编程与信息学竞赛-微信|电话:15892516892
  • Python 算法:最小生成树(Kruskal 算法)
  • 相关推荐

    最新推荐

    热门点击