图简介:
图的表示方式:
邻接矩阵
邻接表
图的代码实现:
1 | import java.util.ArrayList; |
深度优先搜索(DFS):
深度优先遍历,从初始访问结点出发,初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接
结点作为初始结点,访问它的第一个邻接结点。可以理解为:每次都在访问完当前结点后首先访问当前结点的第一个结点。
很明显,深度优先遍历是一个递归的过程。
算法步骤:
1.访问初始结点v,并标记结点v为已访问
2.查找v的第一个邻接结点w
3.若w存在,则继续执行4,如果w不存在,则回到第一步,将从v的下一个节点继续。
4.若w未被访问,对w进行深度优先遍历递归
5.查找节点v的w邻接结点的下一个邻接结点,转到步骤3.
代码实现:
1 | private void dfs(boolean[] isVisited,int i) { |
广度优先搜索(BFS)
图的广度优先搜索类似于树的层序遍历,即访问初始结点后,再依次访问初始结点的邻接结点,当前结点的所有邻接结点访问完成之后,再访问第一个邻接
结点的所有结点,以此类推。
算法算法步骤
1.访问初始结点v并标记为已访问
2.结点v入队列
3.当队列非空时,继续执行,否则算法结束。。。。。
代码实现:
1 | // bfs |
普里姆算法(Prim)
普里姆算法用来求图的最小生成树。该算法的核心思想为贪心。
该算法首先从某一起始结点出发,遍历邻接结点,找出最小的边,并把该结点标记为已访问;然后再以这两个结点为起始结点,分别遍历它们的邻接结点,找出最小的边,
并把该结点标记为已访问,以此类推。
代码实现:
1 | public class Prim { |
克鲁斯卡尔(Kruskal)算法
该算法也是用来求最小生成树,该算法同样用到了贪心思想。
该算法的实现为:首先要对图的所有边权值进行排序,然后依次从小到大取边组成最小生成树,在取的同时还要进行判断是否构成回路的操作,如果构成了回路则要跳过该条边。
注意:判断是否构成回路的算法是理解难点。
代码实现:
1 | public class Kruskal { |
迪杰斯特拉(Dijkstra)算法:
该算法用来求某一结点到其他结点的最短路径。
该算法用到了BFS的思想。它以起始点为中心,向外层层扩展。每次先获取到各结点路径中最短的路径,再在此最短路径基础上更新到其他路径的最短路径。
代码实现:
1 | public class Dijkstra { |
弗洛伊德(Floyd)算法:
核心思想:选取中间结点,比较两个结点本身路径长度与经过中间节点的路径的大小,如果经过中间结点的距离更小, 则更新最短路径矩阵和最短路径前驱结点矩阵。
代码实现:
1 | public class Floyd { |