Python数据结构:图形结构

本章主要内容:

  1. 图的四种表示方法:邻接矩阵法,邻接链表法,邻接复合链表法,索引表格法
  2. 图的遍历:DFS(堆栈+递归),BFS(队列+递归)
  3. 生成树:DFS生成树,BFS生成树,最小生成树(求整个图的最短加权路径)(Kruskal算法:森林->树,Prim算法:树+节点)
  4. 图的最短路径:点到点的最短路径(Dijkstra、Prim、Floyd)
  5. AOV网络与拓扑排序
  6. AOE网络

欧拉环与欧拉链

七桥问题:有七座桥连接4座城市,是否有人能每座桥只经过一次,遍历4座城市,并且回到原点。
欧拉环:将城市视为顶点,桥视为边,只有每个顶点都有偶数多个桥与之相连,才能从某点出发,只经过每条边一次,然后回到起点。
欧拉链:若不要求回到起点,那么起点和终点和奇数多个边相连,其他顶点和偶数多个边相连。

无向图:边没有方向的图
有向图:边有方向的图

图的数据表示法

邻接矩阵法、邻接表法、邻接复合链表法、索引表格法。

邻接矩阵法:
矩阵A,A(i,j)=1表示存在从顶点i到顶点j的边,A(i,j)=0表示不存在从顶点i到顶点j的边。

邻接表法:
表头存放的是顶点,若顶点i到顶点j存在链接,就在表头i后面加上一个节点,值为j。

邻接复合链表法:
每个节点有4个属性,分别是 V 1 , V 2 , L I N K 1 , L I N K 2 V_1,V_2,LINK_1,LINK_2 V1,V2,LINK1,LINK2
V 1 , V 2 V_1,V_2 V1,V2用来表示存在顶点 V 1 V_1 V1到顶点 V 2 V_2 V2的边。
L I N K 1 LINK_1 LINK1存储下一个与 V 1 V_1 V1相连的边的顶点,若没有下一个,则为None。
L I N K 2 LINK_2 LINK2存储下一个与 V 2 V_2 V2相连的边的顶点,若没有下一个,则为None。

索引表格法: 和邻接链表类似,只是用列表存放数据。
由索引与表格两个部分组成。索引部分存放着所有的节点,与每个节点对应的开始的索引。表格部分按序存放着每个节点对应连接的其它节点。

图的遍历

深度优先遍历(DFS)

第一步:从一个点开始,将该点标记为已遍历,将与该点相连的点压入堆栈。

第二步:从堆栈弹出一个元素,将该点标记为已遍历,将与该元素相连,且未 被标记的点压入堆栈。

第三步:重复第二步,直到所有的点都被标记。

广度优先遍历(BFS)

第一步:从一个点开始,将该点标记为已遍历,将与该点相连的点压入队列。

第二步:从队列弹出一个元素,将该点标记为已遍历,将与该元素相连,且未 被标记的点压入队列。

第三步:重复第二步,直到所有的点都被标记。

生成树

一个图的生成树就是以最小的边连通图中所有顶点,且不造成回路的树形结构。

DFS生成树和BFS生成树

用DFS和BFS生成的生成树,就分别叫DFS生成树和BFS生成树。

最小生成树

给树的边加上权重,所有生成树中,权重之和最小的生成树叫做最小生成树。

Kruskal算法

将边的权值按照从小到大的顺序排列,从权值最小的边开始建立最小生成树,若是加入的边会造成回路,就舍弃不用。

具体操作时:

  1. 将所有的节点视为一个森林,每个节点都是森林中的一棵树。
  2. 在边的集合中找到最小的边,判断这条边的两个顶点是否属于某个树,若是不属于,则将这两棵树连接起来。若是属于同一棵树,则什么都不做
  3. 重复操作2,直到左右的顶点都被遍历。

Prim算法:

  1. 图中距离最小的边的两个节点作为树
  2. 计算图中其他树到该树的距离,若是没有直接相连接的边,则距离非常大。选择其中距离最小的节点,加入该树
  3. 重复以上过程直至遍历所有的点。

K算法和P算法很类似,区别在于:
K算法是选择最小的边,相互融合成大树。以边为中心。
P算法是一棵树不断选择和这棵树距离最短的节点。以点为中心。

图的最短路径

从一个点出发,到达另外一个点的加权路径最短的路径叫做图的最短路径。

一个顶点到全部顶点的最短路径通常用Dijkstra算法

Dijkstra算法:

第一步: 计算初始节点S到所有的节点的距离 D ( S , K ) , K ∈ a l l p o i n t D(S,K),K\in all point D(S,K),Kallpoint,无法到达的记为无穷(可以写为一个充分大的整数)。

第二步: 选择当前距离最小的节点A,计算其他节点到A节点的距离,假设存在节点B,满足 D ( S , A ) + D ( A , B ) > D ( S , B ) D(S,A)+D(A,B)>D(S,B) D(S,A)+D(A,B)>D(S,B)则更新 D ( S , B ) D(S,B) D(S,B) D ( S , A ) + D ( A , B ) D(S,A)+D(A,B) D(S,A)+D(A,B)

第三步: 遍历所有的点。 最 后的到的 D ( S , K ) , K ∈ a l l p o i n t D(S,K),K\in all point D(S,K),Kallpoint就是S到各个点的距离。

全部顶点到全部顶点:

Floyd算法:
待补充

也可以用Dijkstra算法求出每个点到所有顶点的最短距离,最终合起来的结果和Floyd相同。

AOV网络与拓扑排序

AOV网络图(Action of Vertex Network)主要用于协助规划大型项目。

网络中的点表示一项事件,有向边表示事件的先后顺序。

拓扑排序就是将网络的次序转换为线性次序。(也就是按照这个顺序可以完成整个项目,且顺序不唯一。)

拓扑排序算法:

第一步: 寻找图中没有先行者的节点。

第二步: 输出该节点,并去除该与该节点相连的边。

第三步: 重复以上两步,直到所有节点都被输出。

AOE网络

AOV网络是指图中的顶点表示一项工作,边表示顶点之间的先后关系。
AOE网络(Action On Edge):顶点作为“进入边事件“汇集点”,当所有“进入边事件”发生后,才可以“外出事件”。

关键路径: 起点到达终点花费时间最长的一条路径。想要缩短总时间,就需要从关键路径下手。

最早时间: 从前往后计算到达节点所需的最大时间。(若第i项工作前有好几个完成时间段,取最大者。)

最晚时间: 从后往前计算到达节点所需的最小时间。(必须要在最小时间点完成,否则会耽误总时间。)

关键顶点: 最晚时间等于最早时间的节点。
最晚时间若是大于最早时间,意味着,该项任务的完成时间具有弹性。
最晚时间若是等于最早时间,意味着,该项任务是关键任务,必须准时完成。

关键节点连接起来的路径就是关键路径,想要提高整个活动的完成时间,就要想办法加快关键路径上事件的完成时间。

参考书籍:《图解数据结构–使用Python》
部分代码请点击

你可能感兴趣的:(数据结构)