图的表示
1.邻接表
一般用于表示稀疏图(Sparse Graph)
2.邻接矩阵
一般用于表示稠密图(Dense Graph)
图的遍历
1.深度优先遍历 DFS
原理与树形结构的DFS一致,从起点开始遍历其连接的所有节点,并以节点为新的起点继续遍历,直至起点没有未被遍历的节点时结束递归。
2.广度优先遍历 BFS
与树形结构的BFS原理一致,使用队列装载起点元素及其连接的节点,每次弹出队首的节点,并以此为起点,填充与之连接的所有未被装载的节点。
3.应用
联通分量,Flood Fill,寻路,走迷宫及迷宫生成,无权图的最短路径,环的判断
最小生成树问题
针对带权无向且连通的图,找出V-1条边连接V个节点,并且要求总权值最小。
1.Prim算法
横切边:如果一条边的两个节点属于切分不同的两边,则这条边称为横切边。
切分定理:给定任意切分,横切边中权值最小的边一定属于最小生成树。
算法描述:开始时以起点为切分的一部分(图中红色部分),寻找权值最小的横切边,随后以起点和之前寻找的横切边连接的另一节点为新的红色部分,继续寻找…每次循环寻找一条横切边和一个节点,V-1次后完成最小生成树。
Lazy Prim,算法复杂度 O(ElogE)
Prim 改进:使用索引堆,动态更新红色部分与外界各节点之间的权值;每次红色部分增加一个节点,将新节点的所有邻接边的权值与索引堆中记录的最小权值比较并更新,算法复杂度O(ElogV)
2.Kruskal算法
算法描述:每次寻找所有边中权值最小的一条,用于构建最小生成树;但需要先使用并查集检验目标边,保证该边的加入不会构成有环图,算法复杂度O(ElogE)
最短路径问题
1.Dijkstra算法
前提条件:图中不能有负权边存在
时间复杂度:O(ElogV)
算法描述:从源点(蓝色部分)开始,使用最小索引堆更新蓝色节点部分到达各个红色节点(未被寻找过的点)的最短路径,再将其中最短的一条边和节点归入蓝色部分(已寻找过的点);以此循环,蓝色部分每次添加一条边和一个节点,直至所有节点都已寻找过
2.Bellman-Ford算法
前提条件:图中不存在负权环
时间复杂度:O(EV)
自检负权环:如果无负权环,则一个节点到另一个节点的最短路径最多经过V个顶点和V-1条边;但存在负权环时,会存在一个顶点经过了两次
算法描述:从源点开始,第n次循环即为寻找经过n条边到达红色节点的路径,使用最小索引堆,更新n次循环中最短的一条路径