一、图的基本概念
图(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

被折叠的 条评论
为什么被折叠?



