数据结构与算法--克鲁斯卡尔算法 最小生成树 Python详细实现克鲁斯卡尔算法 Python详细实现最小生成树

基本概述

  • 先看一个应用场景:
    在这里插入图片描述
  • 克鲁斯卡尔算法介绍:

在这里插入图片描述

克鲁斯卡尔算法图解

  • 还是以上面的公交站图来解释:
  • 最小连通子图(最小生成树):
    在这里插入图片描述
  • 以上图(G4)来说明,假设用数组 R 来保存最小生成树的结果:
    在这里插入图片描述
    在这里插入图片描述
  • 详细描述:

在这里插入图片描述

克鲁斯卡尔算法分析

在这里插入图片描述

  • 如何判断是否构成回路:

在这里插入图片描述

  • 解释上面为什么各点的终点是F:

在这里插入图片描述
在这里插入图片描述
依次将边加入到最小生成树后,形成了一条相连的轨迹(如上图),C 能到到的最后位置就是F,同理D、E也是;对于目前F来说,它的终点就是自身F;所以这几条边都有终点了!

在这里插入图片描述

Python代码实现

补充知识点:如何获取int(long)和 float 的最值
  • 获取 int 型的最大值
import sys

print(sys.maxsize) # 9223372036854775807
# 说明:这个应该为长整形long的最大值,我们对照下Java获取最大的结果来看
'''
Java中获取基本数据类型的最值的方法: 调用基本数据类型的包装类的MIN_VALUE与MAX_VALUE属性即可
具体如下:
- Integer.MIN_VALUE ⇒ -2147483648
- Integer.MAX_VALUE ⇒ 2147483647
- Long.MIN_VALUE ⇒ -9223372036854775808
- Long.MAX_VALUE ⇒ 9223372036854775807
- Float.MIN_VALUE ⇒ 1.4E-45
- Float.MAX_VALUE ⇒ 3.4028235E38
- Double.MIN_VALUE ⇒ 4.9E-324
- Double.MAX_VALUE ⇒ 1.7976931348623157E308
'''

# 注意 Python3 没有Python2 中的sys.maxint方法
  • 获得 float 型的最大值

(1)Python中可以用如下方式表示正、负无穷:

float("inf") # 注意着不是字符串,最大的浮点数就是这个'inf'
print(type(float('inf'))) # <class 'float'>
float("-inf")

(2)利用 inf 做简单加、乘算术运算仍会得到 inf

>>> 1 + float('inf')
inf
>>> 2 * float('inf')
inf

(3)inf 乘以0会得到 not-a-number(NaN);除了inf外的其他数除以inf,会得到0

>>> 0 * float("inf")
nan

>>> 233 / float('inf')
0.0
>>> float('inf') / float('inf')
nan
  • 运用到本次例子:为了更加好看,我们选取float类型的最值来表示
import sys
class GMap(object):
    def __init__(self, vertex_data: [], matrix: []):  # 传入顶点数组
        self.edge_num = 0  # 边的个数
        # self.vertex_data = vertex * [0]  # 顶点数组
        self.vertex_data = vertex_data
        # self.matrix = [[0 for row in range(len(vertex_data))] for col in range(len(vertex_data))]  # 邻接矩阵
        self.matrix = matrix
        # 使用 INF 表示两个顶点不能连通
        self.inf = float('inf')  # 获取浮点型最大值
        # self.inf = sys.maxsize # 获取整形最大值
        # 统计边
        for i in range(len(vertex_data)):
            for j in range(len(vertex_data)):
                if self.matrix[i][j] != self.inf:
                    self.edge_num += 1

    def print_test(self):  # 打印测试
        for i in range(len(self.vertex_data)):
            for j in range(len(self.vertex_data)):
                print(self.matrix[i][j], end=
克鲁斯卡尔算法(Kruskal's algorithm)是一种用于求加权无向连通图的最小生成树算法。其基本思想是按照边的权值从小到大选取 n-1 条边,构造一棵生成树。具体实现可以使用并查集来维护连通性。 下面是一个基于 Python 的 Kruskal 算法实现: ```python # 定义边的类 class Edge: def __init__(self, u, v, w): self.u = u self.v = v self.w = w # 定义并查集类 class UnionFind: def __init__(self, n): self.parent = list(range(n)) self.rank = [0] * n def find(self, x): if x != self.parent[x]: self.parent[x] = self.find(self.parent[x]) return self.parent[x] def union(self, x, y): root_x, root_y = self.find(x), self.find(y) if root_x == root_y: return if self.rank[root_x] < self.rank[root_y]: self.parent[root_x] = root_y elif self.rank[root_x] > self.rank[root_y]: self.parent[root_y] = root_x else: self.parent[root_y] = root_x self.rank[root_x] += 1 # Kruskal 算法 def kruskal(n, edges): uf = UnionFind(n) edges.sort(key=lambda x: x.w) res = [] for edge in edges: u, v, w = edge.u, edge.v, edge.w if uf.find(u) == uf.find(v): continue uf.union(u, v) res.append(edge) if len(res) == n - 1: break return res ``` 其中,`Edge` 类表示一条边,包含起点、终点和权值三个属性。`UnionFind` 类表示并查集,包含 `find` 和 `union` 两个方法。`kruskal` 函数接受节点数 `n` 和边的列表 `edges` 作为输入,返回最小生成树的边列表。 下面是一个使用样例: ```python n = 5 edges = [ Edge(0, 1, 2), Edge(0, 2, 3), Edge(1, 2, 1), Edge(1, 3, 4), Edge(2, 3, 5), Edge(2, 4, 6), Edge(3, 4, 3), ] res = kruskal(n, edges) for edge in res: print(edge.u, edge.v, edge.w) ``` 输出: ``` 1 2 1 0 1 2 3 4 3 0 2 3 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值