数据结构与算法之 leetcode 图论最小生成树 Kruskal 算法

数据结构与算法阿木 发布于 4 天前 3 次阅读


图论最小生成树:Kruskal 算法解析与实现

在图论中,最小生成树(Minimum Spanning Tree,MST)是一个非常重要的概念。它指的是在一个无向、连通的图中,包含图中所有顶点的、权值和最小的生成树。最小生成树在计算机科学、网络设计、数据结构等领域有着广泛的应用。本文将围绕最小生成树这一主题,重点介绍Kruskal算法,并给出相应的代码实现。

Kruskal 算法概述

Kruskal算法是一种基于贪心策略的最小生成树算法。其基本思想是:按照边的权重从小到大排序,依次将边加入生成树中,但每次加入边之前都要检查该边是否与生成树中已有的边构成环。如果构成环,则不加入该边;如果不构成环,则加入该边。

Kruskal算法的时间复杂度主要取决于边的排序过程,通常使用排序算法如快速排序或归并排序,其时间复杂度为O(ElogE),其中E为边的数量。

Kruskal 算法步骤

1. 将所有边按照权重从小到大排序。

2. 初始化一个空的最小生成树T。

3. 遍历排序后的边列表,对于每条边:

a. 检查该边是否与T中的边构成环。

b. 如果不构成环,则将该边加入T中。

4. 重复步骤3,直到T中包含所有顶点。

代码实现

下面是使用Python实现的Kruskal算法:

python

class Edge:


def __init__(self, src, dest, weight):


self.src = src


self.dest = dest


self.weight = weight

class DisjointSet:


def __init__(self, vertices):


self.parent = {v: v for v in vertices}


self.rank = {v: 0 for v in vertices}

def find(self, v):


if self.parent[v] != v:


self.parent[v] = self.find(self.parent[v])


return self.parent[v]

def union(self, u, v):


root_u = self.find(u)


root_v = self.find(v)


if root_u != root_v:


if self.rank[root_u] > self.rank[root_v]:


self.parent[root_v] = root_u


elif self.rank[root_u] < self.rank[root_v]:


self.parent[root_u] = root_v


else:


self.parent[root_v] = root_u


self.rank[root_u] += 1

def kruskal(edges, vertices):


edges.sort(key=lambda x: x.weight)


ds = DisjointSet(vertices)


mst = []


for edge in edges:


if ds.find(edge.src) != ds.find(edge.dest):


ds.union(edge.src, edge.dest)


mst.append(edge)


return mst

示例


vertices = ['A', 'B', 'C', 'D', 'E']


edges = [


Edge('A', 'B', 1),


Edge('A', 'C', 3),


Edge('B', 'C', 1),


Edge('B', 'D', 4),


Edge('C', 'D', 1),


Edge('C', 'E', 5),


Edge('D', 'E', 6)


]

mst = kruskal(edges, vertices)


for edge in mst:


print(f"{edge.src} - {edge.dest} : {edge.weight}")


总结

本文介绍了Kruskal算法的基本原理和实现方法。通过代码示例,我们可以看到Kruskal算法在处理最小生成树问题时的高效性。在实际应用中,Kruskal算法可以用于网络设计、数据结构优化等领域,具有广泛的应用前景。