数据结构 图
时间:2019-05-15 11:57:18
参考:
图#
图由顶点和边组成。图可以通过邻接矩阵(稀疏图)、邻接表(稠密图)或其它方式表示。
图算法#
图遍历算法#
深度优先搜索#
对于给定顶点,依次递归访问第一个邻接节点,第二个邻接节点...
伪代码如下:
1 2 3 4 5 6 7 8 9 |
|
广度优先搜索#
对于给定节点,先访问该节点的所有邻接节点,再访问邻接节点的邻接节点。类似于有层次的访问。通常使用队列作为层次访问的数据结构。
假设洋葱的中心是要访问的初始顶点,中心之外一层的洋葱上的点到中心点的距离为 1,再外面一层上的点到中心的距离为2,依次类推。广度优先搜索要做的就是先把中心外第一层上的点都访问一遍,再把第二层的上的点访问一遍,依次类推。
伪代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Dijkstra 算法#
计算起始点到其它点的最短路径。对于有权图,无权图可以看作点与点之间的路径长度都为1。
初始化工作:
dist[int]
: 表示指定点,到另一个点的最短距离。初始化dist
:起始点为0
,其余为正无穷。path[int]
: 表示经过哪一个点到当前点的路径最短。初始化path
:所有都为-1
,算法完成之后起始点的 path 仍为-1
。visited[boolean]
:记录顶点是否已经访问。
算法描述:
- 访问起始点,标记起始点为已经访问。
- 把起始点的邻接点的
dist[]
赋值为dist[起始点] + 起始点邻到接点的距离
。 - 从没有访问的节点中找一个
dist
值最小的顶点做下一个顶点,记录顶点已访问。如果找不到则算法结束,如果找到继续下一步。 - 比较每一个没有访问的邻接点的
dist[邻接点]
和dist[当前点] + 当前点邻接点的距离
的大小,如果大于则找到了另一条最短的路径,更新dist
的值,并更新path
的值为当前节点。 - 回到第三步。
伪代码:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Floyd 算法#
计算图中所有点之间的最短距离。
准备工作:
以邻接矩阵 Graph[][]
表示的图为例。以二维数组 Dist[][]
记录点到点的最短距离,以二维数组 Path[][]
记录点到点之间的最短路径需要经过的点。
算法描述:
- 初始化
Dist[][]
对角线的值为正无穷。初始化Path[][]
的值为 -1。 - 初始化
Dist[i][j]
的距离为Graph[i][j]
。 - 以矩阵中的第一个点
k
为中间点,比较Dist[i][j]
和Dist[i][k]
+Dist[k][j]
的大小,如果大于则设置Dist[i][j] = Dist[i][k] + dist[k][j]
Path[i][j] = k
。 - 以矩阵中的第二个点为中间点...依次类推直到最后一个点,结束算法。
伪代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
最小生成树算法#
Prim 算法#
从当前已经选择的顶点中选择一条出边最短的路径(出边的下一个顶点不能是已经选择的顶点)。直到已经选择的边的数量为 顶点数 - 1
。
Kruskal 算法#
从所有没有被选择的边中选择一条权值最小的边,把边连接的顶点标记为已经选择。
从所有未选择的边中选择一条权值最小的边,把边连接的顶点加入已选择顶点集合。选择的边不能然已选择的边和组成的图中包含循环。直到选择的边数为 顶点数 - 1
。