首页 > 编程知识 正文

Python数据结构最小生成树

时间:2023-11-19 10:52:42 阅读:297758 作者:TMHC

在这篇文章中,我们将重点介绍Python数据结构中的最小生成树。首先,让我们来回答标题的问题。

最小生成树是一个连通无向图的生成树,并且其所有边的权值之和最小。Python提供了许多数据结构和算法来实现最小生成树的构建和操作。

一、图的表示

在开始之前,我们先来了解一下如何在Python中表示图。图可以通过邻接矩阵或邻接表来表示。

1. 邻接矩阵

邻接矩阵是一个二维数组,用于表示顶点之间的连接关系。矩阵的行和列表示图中的顶点,矩阵中的元素值表示两个顶点之间的边的权值。

class Graph:
    def __init__(self, vertices):
        self.V = vertices
        self.graph = [[0 for _ in range(vertices)] for _ in range(vertices)]

    def add_edge(self, u, v, w):
        self.graph[u][v] = w
        self.graph[v][u] = w

2. 邻接表

邻接表是一个字典,其中每个顶点对应一个链表,存储与其相邻的顶点及边的权值。

from collections import defaultdict

class Graph:
    def __init__(self):
        self.graph = defaultdict(list)

    def add_edge(self, u, v, w):
        self.graph[u].append((v, w))
        self.graph[v].append((u, w))

二、最小生成树算法

有多种算法可以用于构建最小生成树,其中最著名的两种是Prim算法和Kruskal算法。

1. Prim算法

Prim算法是一种贪心算法,从一个顶点开始,逐步扩展生成树。选择与生成树中的顶点相连的具有最小权值的边,并将相邻的顶点加入生成树中。

import sys

class MinimumSpanningTree:
    def __init__(self, vertices):
        self.V = vertices
        self.graph = [[0 for _ in range(vertices)] for _ in range(vertices)]
        self.parent = [None] * vertices

    def min_key(self, key, mst_set):
        min_value = sys.maxsize
        for v in range(self.V):
            if key[v] < min_value and not mst_set[v]:
                min_value = key[v]
                min_index = v
        return min_index

    def prim(self):
        key = [sys.maxsize] * self.V
        key[0] = 0
        mst_set = [False] * self.V

        for _ in range(self.V):
            u = self.min_key(key, mst_set)
            mst_set[u] = True

            for v in range(self.V):
                if self.graph[u][v] > 0 and not mst_set[v] and key[v] > self.graph[u][v]:
                    key[v] = self.graph[u][v]
                    self.parent[v] = u

2. Kruskal算法

Kruskal算法是一种基于集合的算法,按照边的权值从小到大的顺序,逐步选取边,并检查该边是否会形成环路,如果不形成则将其加入生成树中。

class DisjointSet:
    def __init__(self, vertices):
        self.parent = [-1] * vertices

    def find(self, i):
        if self.parent[i] == -1:
            return i
        return self.find(self.parent[i])

    def union(self, x, y):
        x_root = self.find(x)
        y_root = self.find(y)
        self.parent[x_root] = y_root

class MinimumSpanningTree:
    def __init__(self, vertices):
        self.V = vertices
        self.graph = []

    def add_edge(self, u, v, w):
        self.graph.append((u, v, w))

    def kruskal(self):
        self.graph = sorted(self.graph, key=lambda x: x[2])
        disjoint_set = DisjointSet(self.V)
        mst = []

        for edge in self.graph:
            u, v, w = edge
            u_root = disjoint_set.find(u)
            v_root = disjoint_set.find(v)
            if u_root != v_root:
                disjoint_set.union(u_root, v_root)
                mst.append(edge)

三、应用示例

下面以一个应用示例来演示如何使用Python的数据结构实现最小生成树。

def example():
    g = Graph()

    g.add_edge(0, 1, 4)
    g.add_edge(0, 7, 8)
    g.add_edge(1, 2, 8)
    g.add_edge(1, 7, 11)
    g.add_edge(2, 3, 7)
    g.add_edge(2, 8, 2)
    g.add_edge(2, 5, 4)
    g.add_edge(3, 4, 9)
    g.add_edge(3, 5, 14)
    g.add_edge(4, 5, 10)
    g.add_edge(5, 6, 2)
    g.add_edge(6, 7, 1)
    g.add_edge(6, 8, 6)
    g.add_edge(7, 8, 7)

    mst = MinimumSpanningTree(g.V)
    mst.graph = g.graph

    mst.prim()
    print("Prim算法构建的最小生成树:")
    for i in range(1, g.V):
        print(mst.parent[i], "-", i)

    mst.kruskal()
    print("nKruskal算法构建的最小生成树:")
    for edge in mst.mst:
        print(edge[0], "-", edge[1])

example()

通过上述示例,我们可以清楚地了解如何在Python中使用数据结构来构建和操作最小生成树。你可以根据自己的需求选择合适的算法和数据结构来解决问题。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。