有向图的介绍
引入
- 在实际生活中,很多应用相关的图都是有方向性的,最直观的就是网络,可以从A页面通过链接跳转到B页面,那么a和b连接的方向是a->b,但不能说是b->a,此时我们就需要使用有向图来解决这一类问题,它和我们之前学习的无向图,最大的区别就在于连接是具有方向的,在代码的处理上也会有很大的不同。
定义
- 有向图(Digraph或Directed graph)是一副由一系列顶点和连接顶点之间的具有方向性的边组成的图
这是一幅简单的有向图示意,其中双向箭头的边实际上是由两条不同的边组成的
有向图的术语
- 出度:由某个顶点指出的边的个数称为该顶点的出度。
- 入度:指向某个顶点的边的个数称为该顶点的入度。
- 有向路径:由一系列顶点组成,对于其中的每个顶点都存在一条有向边,从它指向序列中的下一个顶点。
- 有向环:至少含有一条边,且起点和终点相同的有向路径。
一副有向图中两个顶点v和w可能存在以下四种关系:
- 没有边相连;
- 存在从v到w的边v- ->W;
- 存在从w到v的边w- ->v;
- 既存在w到v的边,也存在v到w的边,即双向连接;
有向图的实现
属性方法设计
类名:Edge
- 构造方法__init__()中的属性
num_vertices和num_edges分别代表要构造的图的顶点和边的数量;adj_list是一个列表,其索引代表顶点,储存的值是与索引对应顶点相邻的全部顶点 - point_edge(x, y) 对传入的两个顶点x,y构造一条边:x→y
- point_to_vertices(x) 获取传入的顶点x所有指出的顶点
- reverse_digraph() 将当前图中的所有边的方向反转获得一张反转图并返回
Python代码实现
class Digraph:def __init__(self, num):self.num_vertices = numself.num_edges = 0self.adj_list = [[] for _ in range(num)]def count_vertices(self):return self.num_verticesdef count_edges(self):return self.num_edgesdef point_edge(self, x, y):"""Add an edge of vertex x: x --> y"""self.adj_list[x].append(y)def point_to_vertices(self, x):return self.adj_list[x]def reverse_digraph(self):rvs_digraph = Digraph(self.num_vertices)for index, queue in enumerate(self.adj_list):for v in queue:rvs_digraph.point_edge(v, index)return rvs_digraphif __name__ == '__main__':graph = Digraph(5)graph.point_edge(3, 0)graph.point_edge(0, 2)graph.point_edge(2, 0)graph.point_edge(2, 1)graph.point_edge(1, 0)graph.point_edge(1, 4)print(graph.point_to_vertices(1))print(graph.adj_list)rvs_graph = graph.reverse_digraph()print(rvs_graph.adj_list)
运行结果
[0, 4]
[[2], [0, 4], [0, 1], [0], []]
[[1, 2, 3], [2], [0], [], [1]]