Python数据结构:图形结构

本章主要内容:html

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

欧拉环与欧拉链

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

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

图的数据表示法

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

邻接矩阵法:
矩阵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
V 1 , V 2 V_1,V_2 用来表示存在顶点 V 1 V_1 到顶点 V 2 V_2 的边。
L I N K 1 LINK_1 存储下一个与 V 1 V_1 相连的边的顶点,若没有下一个,则为None。
L I N K 2 LINK_2 存储下一个与 V 2 V_2 相连的边的顶点,若没有下一个,则为None。数据结构

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

图的遍历

深度优先遍历(DFS)svg

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

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

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

广度优先遍历(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 ,没法到达的记为无穷(能够写为一个充分大的整数)。

第二步: 选择当前距离最小的节点A,计算其余节点到A节点的距离,假设存在节点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 , 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 就是S到各个点的距离。

所有顶点到所有顶点:

Floyd算法:
待补充

也能够用Dijkstra算法求出每一个点到全部顶点的最短距离,最终合起来的结果和Floyd相同。

AOV网络与拓扑排序

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

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

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

拓扑排序算法:

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

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

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

AOE网络

AOV网络是指图中的顶点表示一项工做,边表示顶点之间的前后关系。
AOE网络(Action On Edge):顶点做为“进入边事件“聚集点”,当全部“进入边事件”发生后,才能够“外出事件”。

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

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

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

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

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

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