一个网站有多大营口软件开发
web/
2025/9/27 7:23:27/
文章来源:
一个网站有多大,营口软件开发,南昌公司做网站,温州市人才市场招聘网最新招聘目录
图的遍历概念#xff1a;
图的广度优先遍历#xff08;BFS#xff09;#xff1a;
代码实现如下#xff1a;
测试如下#xff1a;
注意#xff1a;
图的深度优先遍历#xff08;DFS#xff09;#xff1a;
代码实现如下#xff1a;
测试如下#xff1…目录
图的遍历概念
图的广度优先遍历BFS
代码实现如下
测试如下
注意
图的深度优先遍历DFS
代码实现如下
测试如下
总代码
结语 图的遍历概念
给定一个图G和其中任意一个顶点v0从v0出发沿着图中各边访问图中的所有顶点且每个顶点仅被遍历一次。遍历即对结点进行某种操作的意思。由于考试大多考邻接矩阵(GraphByMatrix)故下面的遍历都是用邻接矩阵(GraphByMatrix)不是邻接表(GraphByNode)。
图的广度优先遍历BFS
广度优先遍历类似于我们前面所学二叉树的层序遍历一层一层的走故可以使用队列来模拟实现。 比如现在有三个抽屉每个抽屉包含一个红色盒子红色盒子中又包含一个绿色盒子所需东西在那个抽屉不清楚现在要将其找到广度优先遍历的做法是 1先将三个抽屉打开在最外层找一遍。 2将每个抽屉中红色的盒子打开再找一遍。 3最后将红色盒子中绿色盒子打开再找一遍。 直到找完所有的盒子注意每个盒子只能找一次不能重复找。 例如下图 该图的广度优先遍历过程如下
故其广度优先遍历的结果为ABCDEFGHI。 代码实现如下 1、初始化一个布尔类型数组visited默认所有顶点都没有被遍历到。 2、获取当前开始的顶点V 的下标。 3、定义一个队列存储当前需要遍历的顶点的下标。 4、取出当前队列的头部。 5、把当前的顶点的这一行都放到队列。 由于getIndexOfVarrayVmatrix在上一篇文章中已经非常详细的描述过故这里我只解释其作用如若需要源码和更加详细的解释请友友前往图的存储结构 1geiIndexOfV 获取顶点元素在其数组中的下标 。 2arrayV 顶点元素的一维数组。 3matrix 利用matrix二维数组来存储顶点之间边的权重。 /*** 广度优先遍历* param v*/public void bfs(char v){//1、初始化一个布尔类型数组默认所有顶点都没有被遍历到boolean[] visited new boolean[arrayV.length];//2、获取当前开始的顶点V的下标int index getIndexOfV(v);//3、定义一个队列存储当前需要遍历的顶点的下标QueueInteger qu new LinkedList();qu.offer(index);//起点放进来while(!qu.isEmpty()){//4、取出当前队列的头部int top qu.poll();System.out.print(arrayV[top]:- );visited[top] true;//5、把当前的顶点的这一行都放到队列for(int i 0;i arrayV.length;i){//如果这一行的i下标不等于MAX_VALUE并且也没有被访问过if(matrix[top][i] ! Integer.MAX_VALUE visited[i] false){qu.offer(i);//注意防止重复打印visited[i] true;}}}System.out.println(null);}
测试如下
测试代码均围绕下图进行 遍历结果为BACD显然符合我们的预期。
注意
下面话红线的地方不能省去。 如若省去会发生重复遍历例如
发生了DD的重复打印。
那为什么会发生重复打印呢这是因为在C出队时D已经在队列中了但是其还是false故C出队会再次把D入队这样就会重复打印。具体过程如下动图 解决方法在入队时一起把元素对应下标的visited数组设置为false。
为了方便友友调试下面将测试代码给出
public static void main(String[] args) {GraphByMatrix graph new GraphByMatrix(4,true);char[] array {A,B,C,D};graph.initArrayV(array);graph.addEdge(A,B,1);graph.addEdge(A,D,1);graph.addEdge(B,A,1);graph.addEdge(B,C,1);graph.addEdge(C,B,1);graph.addEdge(C,D,1);graph.addEdge(D,A,1);graph.addEdge(D,C,1);graph.bfs(B);}
图的深度优先遍历DFS
图的深度优先遍历类似于前面所学二叉树的前序遍历有路就走走完没路了再回退使用递归来实现。 比如现在有三个抽屉每个抽屉包含一个红色盒子红色盒子中又包含一个绿色盒子所需东西在那个抽屉不清楚现在要将其找到深度优先遍历的做法是 1先将第一个抽屉打开在最外层找一遍。 2将第一个抽屉中红色的盒子打开在红色箱子里找一遍。 3将红色盒子中绿色盒子打开在绿箱子里找一遍。 4递归查找剩余两个箱子。 深度优先遍历将一个抽屉一次性遍历完包括该抽屉中包含的小盒子再去递归遍历其它盒子。
其过程如图所示 其深度优先遍历结果为ABEGCFDHI。
代码实现如下
实现一个方法dfschild来进行递归为什么不用dfs直接递归呢这是因为如果直接把dfs递归哪visited会一直被开辟堆上的内存占用太大要把visited设置在dfs外面才行。
部分流程和前面所说的广度优先遍历类似关于getIndexOfVarrayVmatrix在广度优先遍历那已解释故这里不再过多描述。 /*** 给定顶点从顶点处开始进行深度优先遍历* param v*/public void dfs(char v){//1、初始化一个布尔类型数组默认所有顶点都没有被遍历到boolean[] visited new boolean[arrayV.length];//2、获取当前开始的顶点V 的下标int index getIndexOfV(v);//3、开始从index位置进行深度遍历dfsChild(index,visited);System.out.print(null);}/*** 从index位置开始深度优先遍历* param index* param visited*/private void dfsChild(int index,boolean[] visited){System.out.print(arrayV[index]:- );visited[index] true;//当前index位置的所有的连接点都在这一行for(int i 0;i arrayV.length;i){//如果这一行的i下标不等于0并且也没有被访问过if(matrix[index][i] ! Integer.MAX_VALUE visited[i] false){dfsChild(i,visited);}}}
测试如下
遍历结果为BADC显然符合我们的预期。 总代码
import java.sql.SQLOutput;
import java.util.Arrays;
import java.util.Queue;
import java.util.LinkedList;
public class GraphByMatrix {private char[] arrayV;//存放顶点·private int[][] matrix;//存放边private boolean isDirect;//是否是有向图public GraphByMatrix(int size,boolean isDirect){arrayV new char[size];matrix new int[size][size];for(int i 0;i size;i){Arrays.fill(matrix[i],Integer.MAX_VALUE);}this.isDirect isDirect;}/*** 初始化* param array 顶点集合*/public void initArrayV(char[] array){for(int i 0;i array.length;i){arrayV[i] array[i];}}/**** param v1 起始* param v2 终点* param weight 权值*/public void addEdge(char v1,char v2,int weight){int index1 getIndexOfV(v1);int index2 getIndexOfV(v2);matrix[index1][index2] weight;if(!isDirect){matrix[index2][index1] weight;}}/*** 获取顶点元素在其数组中的下标* param v* return*/public int getIndexOfV(char v){for(int i 0;i arrayV.length;i){if(v arrayV[i]){return i;}}return -1;}/*** 获取顶点的度* param v* return*/public int getDevOfV(char v){int indexV getIndexOfV(v);int count 0;for(int i 0;i arrayV.length;i){if(matrix[indexV][i] ! Integer.MAX_VALUE){count;}}if(isDirect){for(int i 0;i arrayV.length;i){if(matrix[i][indexV] ! Integer.MAX_VALUE){count;}}}return count;}public void printGraph(){for(int i 0;i arrayV.length;i){System.out.print(arrayV[i] );}System.out.println();for(int i 0;i matrix.length;i){for(int j 0;j matrix[i].length;j){if(matrix[i][j] Integer.MAX_VALUE) {System.out.print(∞ );}else {System.out.print(matrix[i][j] );}}System.out.println();}}//广度优先遍历/*** 广度优先遍历* param v*/public void bfs(char v){//1、初始化一个布尔类型数组默认所有顶点都没有被遍历到boolean[] visited new boolean[arrayV.length];//2、获取当前开始的顶点V的下标int index getIndexOfV(v);//3、定义一个队列存储当前需要遍历的顶点的下标QueueInteger qu new LinkedList();qu.offer(index);//起点放进来while(!qu.isEmpty()){//4、取出当前队列的头部int top qu.poll();System.out.print(arrayV[top]:- );visited[top] true;//5、把当前的顶点的这一行都放到队列for(int i 0;i arrayV.length;i){//如果这一行的i下标不等于MAX_VALUE并且也没有被访问过if(matrix[top][i] ! Integer.MAX_VALUE visited[i] false){qu.offer(i);//注意防止重复打印
// visited[i] true;}}}System.out.println(null);}//图的深度优先遍历/*** 给定顶点从顶点处开始进行深度优先遍历* param v*/public void dfs(char v){//1、初始化一个布尔类型数组默认所有顶点都没有被遍历到boolean[] visited new boolean[arrayV.length];//2、获取当前开始的顶点V 的下标int index getIndexOfV(v);//3、开始从index位置进行深度遍历dfsChild(index,visited);System.out.print(null);}/*** 从index位置开始深度优先遍历* param index* param visited*/private void dfsChild(int index,boolean[] visited){System.out.print(arrayV[index]:- );visited[index] true;//当前index位置的所有的连接点都在这一行for(int i 0;i arrayV.length;i){//如果这一行的i下标不等于0并且也没有被访问过if(matrix[index][i] ! Integer.MAX_VALUE visited[i] false){dfsChild(i,visited);}}}
}结语
其实写博客不仅仅是为了教大家同时这也有利于我巩固自己的知识点和一个学习的总结由于作者水平有限对文章有任何问题的还请指出接受大家的批评让我改进如果大家有所收获的话还请不要吝啬你们的点赞收藏和关注这可以激励我写出更加优秀的文章。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/81217.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!