Python 图的基本知识与实现

一、图的基本概念

图(Graph)是由顶点(Vertex)和边(Edge)组成的非线性数据结构,表示为 G = (V, E),其中:

  • V 是顶点集合
  • E 是边集合

图的分类

  • 无向图:边没有方向,(A,B) 和 (B,A) 表示同一条边
  • 有向图:边有方向,A→B 不同于 B→A
  • 加权图:边带有权重/成本
  • 无权图:边没有权重

二、图的表示方法

1、邻接矩阵

使用二维数组表示顶点间的连接关系

class GraphMatrix:
    """邻接矩阵表示图"""
    def __init__(self, num_vertices):
        self.num_vertices = num_vertices
        self.matrix = [[0] * num_vertices for _ in range(num_vertices)]
    
    def add_edge(self, v1, v2, weight=1):
        """添加边"""
        self.matrix[v1][v2] = weight
        # 如果是无向图,还需要对称设置
        # self.matrix[v2][v1] = weight
    
    def __str__(self):
        """可视化邻接矩阵"""
        return '\n'.join([' '.join(map(str, row)) for row in self.matrix])

# 创建有向图
g = GraphMatrix(4)
g.add_edge(0, 1)  # 0→1
g.add_edge(0, 2)  # 0→2
g.add_edge(1, 2)  # 1→2
g.add_edge(2, 0)  # 2→0
g.add_edge(2, 3)  # 2→3

print("邻接矩阵:")
print(g)
# 输出:
# 0 1 1 0
# 0 0 1 0
# 1 0 0 1
# 0 0 0 0

2、邻接表

使用字典或列表表示每个顶点的邻接顶点

class GraphAdjList:
    """邻接表表示图"""

    def __init__(self):
        self.adj_list = {}

    def add_vertex(self, vertex):
        """添加顶点"""
        if vertex not in self.adj_list:
            self.adj_list[vertex] = []

    def add_edge(self, v1, v2, weight=None):
        """添加边"""
        if v1 not in self.adj_list:
            self.add_vertex(v1)
        if v2 not in self.adj_list:
            self.add_vertex(v2)
        self.adj_list[v1].append((v2, weight))
        # 如果是无向图,还需要反向添加
        # self.adj_list[v2].append((v1, weight))

    def __str__(self):
        """可视化邻接表"""
        result = []
        for vertex in self.adj_list:
            connections = ', '.join(
                f"{v}({w})" if w is not None else str(v)
                for v, w in self.adj_list[vertex]
            )
            result.append(f"{vertex}: {connections}")
        return '\n'.join(result)


# 创建加权有向图
g = GraphAdjList()
g.add_edge('A', 'B', 4)
g.add_edge('A', 'D', 5)
g.add_edge('A', 'C', 2)
g.add_edge('B', 'C', 5)
g.add_edge('C', 'D', 1)
g.add_edge('D', 'A', 3)

print("\n邻接表:")
print(g)
# 输出:
# A: B(4), D(5), C(2)
# B: C(5)
# D: A(3)
# C: D(1)

三、图的遍历算法

1、深度优先搜索

# 深度优先算法
def dfs(graph, start, visited=None):
    """深度优先搜索 (递归实现)"""
    if visited is None:
        visited = set()
    visited.add(start)
    print(start, end=' ')

    for neighbor, _ in graph.adj_list.get(start, []):
        if neighbor not in visited:
            dfs(graph, neighbor, visited)


print("\nDFS遍历:")
dfs(g, 'A')  # 输出: A B C D

2、广度优先算法

# 广度优先算法
from collections import deque


def bfs(graph, start):
    """广度优先搜索"""
    visited = set()
    queue = deque([start])
    visited.add(start)

    while queue:
        vertex = queue.popleft()
        print(vertex, end=' ')

        for neighbor, _ in graph.adj_list.get(vertex, []):
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)


print("\nBFS遍历:")
bfs(g, 'A')  # 输出: A B D C

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值