python无向图有向图基本操作

from queue import Queue
import sys


class DirectedGraph:
    def __init__(self, num_vertices):
        self.num_vertices = num_vertices
        self.adj_matrix = [[0] * num_vertices for _ in range(num_vertices)]
        self.adj_list = [[] for _ in range(num_vertices)]

    def add_edge(self, start_vertex, end_vertex, weight=1):
        if 0 <= start_vertex < self.num_vertices and 0 <= end_vertex < self.num_vertices:
            self.adj_matrix[start_vertex][end_vertex] = weight
            self.adj_list[start_vertex].append((end_vertex, weight))

    def remove_edge(self, start_vertex, end_vertex):
        if 0 <= start_vertex < self.num_vertices and 0 <= end_vertex < self.num_vertices:
            self.adj_matrix[start_vertex][end_vertex] = 0
            self.adj_list[start_vertex] = [(v, w) for v, w in self.adj_list[start_vertex] if v != end_vertex]

    @classmethod
    def from_adjacency_matrix(cls, adj_matrix):
        num_vertices = len(adj_matrix)
        graph = cls(num_vertices)
        for i in range(num_vertices):
            for j in range(num_vertices):
                weight = adj_matrix[i][j]
                if weight != 0:
                    graph.add_edge(i, j, weight)
        return graph

    @classmethod
    def from_adjacency_list(cls, adj_list):
        num_vertices = len(adj_list)
        graph = cls(num_vertices)
        for start_vertex, neighbors in enumerate(adj_list):
            for end_vertex, weight in neighbors:
                graph.add_edge(start_vertex, end_vertex, weight)
        return graph


class UndirectedGraph:
    def __init__(self, num_vertices):
        self.num_vertices = num_vertices
        self.adj_matrix = [[0] * num_vertices for _ in range(num_vertices)]
        self.adj_list = [[] for _ in range(num_vertices)]

    def add_edge(self, vertex1, vertex2, weight=1):
        if vertex1 >= 0 and vertex1 < self.num_vertices and vertex2 >= 0 and vertex2 < self.num_vertices:
            self.adj_matrix[vertex1][vertex2] = weight
            self.adj_matrix[vertex2][vertex1] = weight
            self.adj_list[vertex1].append((vertex2, weight))
            self.adj_list[vertex2].append((vertex1, weight))

    def remove_edge(self, vertex1, vertex2):
        if 0 <= vertex1 < self.num_vertices and 0 <= vertex2 < self.num_vertices:
            self.adj_matrix[vertex1][vertex2] = 0
            self.adj_matrix[vertex2][vertex1] = 0
            self.adj_list[vertex1] = [(v, w) for v, w in self.adj_list[vertex1] if v != vertex2]
            self.adj_list[vertex2] = [(v, w) for v, w in self.adj_list[vertex2] if v != vertex1]

    def depth_first_traversal(self, start_vertex):
        visited = [False] * self.num_vertices
        self._depth_first_traversal_recursive(start_vertex, visited)

    def _depth_first_traversal_recursive(self, vertex, visited):
        visited[vertex] = True
        print(vertex, end=" ")
        for neighbor, _ in self.adj_list[vertex]:
            if not visited[neighbor]:
                self._depth_first_traversal_recursive(neighbor, visited)

    def breadth_first_traversal(self, start_vertex):
        visited = [False] * self.num_vertices
        queue = Queue()
        visited[start_vertex] = True
        queue.put(start_vertex)

        while not queue.empty():
            vertex = queue.get()
            print(vertex, end=" ")

            for neighbor, _ in self.adj_list[vertex]:
                if not visited[neighbor]:
                    visited[neighbor] = True
                    queue.put(neighbor)

    @classmethod
    def from_adjacency_matrix(cls, adj_matrix):
        num_vertices = len(adj_matrix)
        graph = cls(num_vertices)
        for i in range(num_vertices):
            for j in range(i, num_vertices):
                weight = adj_matrix[i][j]
                if weight != 0:
                    graph.add_edge(i, j, weight)
        return graph

    def minimum_spanning_tree(self):
        visited = [False] * self.num_vertices
        key = [sys.maxsize] * self.num_vertices
        parent = [None] * self.num_vertices

        key[0] = 0  # Choose the first vertex as the starting point

        for _ in range(self.num_vertices):
            u = self._min_key_vertex(key, visited)
            visited[u] = True

            for v, weight in self.adj_list[u]:
                if not visited[v] and weight < key[v]:
                    key[v] = weight
                    parent[v] = u

        mst_adj_list = [[] for _ in range(self.num_vertices)]
        for v in range(1, self.num_vertices):
            u = parent[v]
            weight = key[v]
            mst_adj_list[u].append((v, weight))
            mst_adj_list[v].append((u, weight))

        mst = UndirectedGraph(self.num_vertices)
        mst.adj_list = mst_adj_list

        return mst

    def _min_key_vertex(self, key, visited):
        min_key = sys.maxsize
        min_vertex = -1

        for v in range(self.num_vertices):
            if not visited[v] and key[v] < min_key:
                min_key = key[v]
                min_vertex = v

        return min_vertex


if __name__ == '__main__':

    # 从邻接表建立有向图
    adj_list = [
        [(1, 5), (2, 4)],
        [(3, 7), (4, 5)],
        [(3, 3), (4, 6)],
        [(5, 5)],
        [(5, 3)],
        []
    ]
    directed_graph = DirectedGraph.from_adjacency_list(adj_list)

    # 从邻接矩阵建立有向图
    adj_matrix = [
        [0, 5, 4, 0, 0, 0],
        [0, 0, 0, 7, 5, 0],
        [0, 0, 0, 3, 6, 0],
        [0, 0, 0, 0, 0, 5],
        [0, 0, 0, 0, 0, 3],
        [0, 0, 0, 0, 0, 0]
    ]

    directed_graph2 = DirectedGraph.from_adjacency_matrix(adj_matrix)

    # 打印有向图的邻接矩阵和邻接表
    print("有向图邻接矩阵:")
    for row in directed_graph.adj_matrix:
        print(row)

    print("有向图邻接表:")
    for i, vertex in enumerate(directed_graph.adj_list):
        print(f"Vertex {i}: {vertex}")

    # 建立无向图
    undirected_graph = UndirectedGraph.from_adjacency_matrix(adj_matrix)

    # 打印无向图的邻接矩阵和邻接表
    print("无向图邻接矩阵:")
    for row in undirected_graph.adj_matrix:
        print(row)

    print("深度优先遍历:")
    undirected_graph.depth_first_traversal(0)
    print("\n广度优先遍历:")
    undirected_graph.breadth_first_traversal(0)

    mst = undirected_graph.minimum_spanning_tree()

    print("\n最小生成树的邻接表:")
    for i, vertex in enumerate(mst.adj_list):
        print(f"Vertex {i}: {vertex}")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值