图的遍历(Java)构造器
图的遍历
一、DFS(Depth First Search)
概念:
从初始访问点出发,访问其第一个邻接节点;然后把这个邻接节点作为初始节点,继续访问它的第一个邻接节点。
即每次都在访问完当前节点过后,访问它的第一个邻接节点。
算法:
- 访问初始节点v(下标),并标记v已被访问;
- 查找节点v的第一个邻接节点w(下标);
- 如果w存在,则继续
4
步骤;如果w不存在,则返回1
步骤; - 如果w未被访问过,对w进行dfs递归操作(重复
1
、2
、3
操作); - 查找节点v的w邻接节点的下一个邻接节点,返回
3
步骤
源代码如下:
import java.util.ArrayList;
import java.util.Arrays;public class graph {private ArrayList<String> vertexList;// 定义顶点列表private int[][] edges;// 存储图对应的邻接矩阵private int numOfEdges;// 存储边private boolean isVisited[];// 标记顶点是否已被访问public static void main(String[] args) {// TODO Auto-generated method stub// 测试图int n = 5;// 定义顶点个数String vertexs[] = { "A", "B", "C", "D", "E" };// 创建图对象graph graph = new graph(n);// 循环添加顶点for (String vertex : vertexs) {// 每次循环从vertexValue取出来一个值(定义为value)graph.insertVertex(vertex);// 把顶点加进去}// 添加边// A-B A-C B-C B-D B-E// 权值默认为是1graph.insertEdges(0, 1, 1);// A-Bgraph.insertEdges(0, 2, 1);// A-Cgraph.insertEdges(1, 2, 1);// B-Cgraph.insertEdges(1, 3, 1);// B-Dgraph.insertEdges(1, 4, 1);// B-E// 显示邻接矩阵graph.show();// DFSgraph.dfs();}// ————————————--------------------------------------------------------// 首先定义图的属性// 1.构造器public graph(int n) {// 首先要传入顶点的数目// 初始化矩阵和vertexListedges = new int[n][n];vertexList = new ArrayList<String>();// 初始化顶点列表numOfEdges = 0;// 可省略,因为默认为0isVisited = new boolean[5];}// 2.插入顶点public void insertVertex(String vertex) {vertexList.add(vertex);}// 3.设置边/*** * @param v1 第一个顶点的下标* @param v2 第二个顶点的下标* @param weight 权值*/public void insertEdges(int v1, int v2, int weight) {// 这里是定义无向图,所以两个方向都要定义edges[v1][v2] = weight;edges[v2][v1] = weight;numOfEdges++;}// 4.返回顶点个数public int getnumOfVertexs() {return vertexList.size();}// 5.返回边个数public int getnumOfEdges() {return numOfEdges;}// 6.返回顶点i(顶点的下标)的对应的数据/*** * @param i返回数据下标* @return 返回数据 例:0->A 1->B 2->C 3->D 4->E*/public String getValueByIndex(int i) {return vertexList.get(i);}// 7.返回v1,v2两顶点之间的权值public int getWeight(int v1, int v2) {return edges[v1][v2];}// 8.打印邻接矩阵(本质:遍历图)public void show() {for (int[] link : edges) {System.out.println(Arrays.toString(link));}}
//————————————-------------------------------------------------------- // DFS算法步骤// 1.得到第一个邻接节点下标w/*** * @param index* @return 如果存在就返回它的下标,没有就返回-1*/public int getFirstNerghborIndex(int index) {// 传入当前节点的下标indexfor (int w = 0; w < vertexList.size(); w++) {if (edges[index][w] > 0) {// 如果下一个邻接节点存在return w;// 返回它的下标}}return -1;// 没有返回就返回-1}// 2.根据前一个邻接节点的下标来获取下一个邻接节点/*** * @param v1* @param v2* @return*/public int getNextNeighbor(int v1, int v2) {for (int w = v2 + 1; w < vertexList.size(); w++) {if (edges[v1][w] > 0) {return w;}}return -1;}// 3.开始深搜遍历public void dfs(boolean[] isVisited, int i) {// 判断是否遍历过的标记,定义节点下标// 首先访问当前节点,输出System.out.print(getValueByIndex(i) + "->");// 访问过后,要标记节点已访问isVisited[i] = true;// 查找节点i的第一个邻接节点int w = getFirstNerghborIndex(i);while (w != -1) {// 存在if (!isVisited[w]) {// 如果没有被标记过dfs(isVisited, w);// 以w为初始节点重新开始,递归操作dfs}// 如果已经被访问过w = getNextNeighbor(i, w);}}// 对dfs进行重载,遍历所有节点public void dfs() {for (int i = 0; i < getnumOfVertexs(); i++) {while (!isVisited[i]) {// 如果没被访问过dfs(isVisited, i);}}}
}
二、BFS(Broad First Search)
.addLast() | 获取最后一个节点 |
---|
概念:
类似一个分层搜索过程,BFS需要一个队列以保持访问过节点的顺序,以便按照这个顺序来访问他们的邻接节点。
算法:
- 访问初始节点v,并将其标记已经访问;
- 把节点v加入队列;
- 当队列非空时,继续执行,否则算法结束;
- 出队列,取得队头结点u;
- 查找初始节点也是队头结点u第一个邻接节点w;
- 若节点u的第一个邻接节点w不存在,执行步骤
3
,否则循环执行下述三个操作:
(1)若节点w未被访问,访问它并标记已经访问;
(2)节点w入队列;
(3)查找节点u的继w邻接节点后的下一个邻接节点,转到步骤6
。
源代码如下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;public class graph {private ArrayList<String> vertexList;// 定义顶点列表private int[][] edges;// 存储图对应的邻接矩阵private int numOfEdges;// 存储边private boolean isVisited[];// 标记顶点是否已被访问public static void main(String[] args) {// TODO Auto-generated method stub// 测试图int n = 5;// 定义顶点个数String vertexs[] = { "A", "B", "C", "D", "E" };// 创建图对象graph graph = new graph(n);// 循环添加顶点for (String vertex : vertexs) {// 每次循环从vertexValue取出来一个值(定义为value)graph.insertVertex(vertex);// 把顶点加进去}// 添加边// A-B A-C B-C B-D B-E// 权值默认为是1graph.insertEdges(0, 1, 1);// A-Bgraph.insertEdges(0, 2, 1);// A-Cgraph.insertEdges(1, 2, 1);// B-Cgraph.insertEdges(1, 3, 1);// B-Dgraph.insertEdges(1, 4, 1);// B-E// 显示邻接矩阵graph.show();/*// DFSSystem.out.println();System.out.println("DFS:");graph.dfs();*/System.out.println();System.out.println();System.out.println("BFS:");graph.bfs();}// ————————————--------------------------------------------------------// 首先定义图的属性// 1.构造器public graph(int n) {// 首先要传入顶点的数目// 初始化矩阵和vertexListedges = new int[n][n];vertexList = new ArrayList<String>();// 初始化顶点列表numOfEdges = 0;// 可省略,因为默认为0isVisited = new boolean[vertexList.size() + 1];}// 2.插入顶点public void insertVertex(String vertex) {vertexList.add(vertex);}// 3.设置边/*** * @param v1 第一个顶点的下标* @param v2 第二个顶点的下标* @param weight 权值*/public void insertEdges(int v1, int v2, int weight) {// 这里是定义无向图,所以两个方向都要定义edges[v1][v2] = weight;edges[v2][v1] = weight;numOfEdges++;}// 4.返回顶点个数public int getnumOfVertexs() {return vertexList.size();}// 5.返回边个数public int getnumOfEdges() {return numOfEdges;}// 6.返回顶点i(顶点的下标)的对应的数据/*** * @param i返回数据下标* @return 返回数据 例:0->A 1->B 2->C 3->D 4->E*/public String getValueByIndex(int i) {return vertexList.get(i);}// 7.返回v1,v2两顶点之间的权值public int getWeight(int v1, int v2) {return edges[v1][v2];}// 8.打印邻接矩阵(本质:遍历图)public void show() {for (int[] link : edges) {System.out.println(Arrays.toString(link));}}
//————————————-------------------------------------------------------- // DFS算法步骤// 1.得到第一个邻接节点下标w/*** * @param index* @return 如果存在就返回它的下标,没有就返回-1*/public int getFirstNerghborIndex(int index) {// 传入当前节点的下标indexfor (int w = 0; w < vertexList.size(); w++) {if (edges[index][w] > 0) {// 如果下一个邻接节点存在return w;// 返回它的下标}}return -1;// 没有返回就返回-1}// 2.根据前一个邻接节点的下标来获取下一个邻接节点/*** * @param v1为前驱点* @param v2为前驱点的当前邻接节点* @return*/public int getNextNeighbor(int v1, int v2) {for (int w = v2 + 1; w < vertexList.size(); w++) {if (edges[v1][w] > 0) {return w;}}return -1;}// 3.开始深搜遍历private void dfs(boolean[] isVisited, int i) {// 判断是否遍历过的标记,定义节点下标// 首先访问当前节点,输出System.out.print(getValueByIndex(i) + "->");// 访问过后,要标记节点已访问isVisited[i] = true;// 查找节点i的第一个邻接节点int w = getFirstNerghborIndex(i);while (w != -1) {// 存在if (!isVisited[w]) {// 如果没有被标记过dfs(isVisited, w);// 以w为初始节点重新开始,递归操作dfs}// 如果已经被访问过// 以u为前驱点,找w的下一个邻接节点// w为辅助变量,每次进行此操作的时候更新值w = getNextNeighbor(i, w);}}// 对dfs进行重载,遍历所有节点public void dfs() {for (int i = 0; i < getnumOfVertexs(); i++) {while (!isVisited[i]) {// 如果没被访问过dfs(isVisited, i);}}}// ————————————--------------------------------------------------------// BFS算法步骤private void bfs(boolean[] isVisited, int i) {int u;// 初始节点,队头结点int w;// 邻接节点// 使用队列记录访问节点的顺序LinkedList queue = new LinkedList();// 访问节点(输出节点信息)System.out.print(getValueByIndex(i) + "->"); 标记为已访问isVisited[i] = true;// 若已访问,添加节点到队列queue.addLast(i);// 重复操作while (!queue.isEmpty()) {// 如果队列不为空// 取出队列的头节点下标u = (Integer) queue.removeFirst();// 得到第一个邻接节点的下标ww = getFirstNerghborIndex(u);while (w != -1) {// 找到邻接节点// 判断是否访问过if (!isVisited[w]) {// 如果没有访问过System.out.print(getValueByIndex(w) + "->");// 访问isVisited[w] = true;// 标记为已访问// 邻接节点入队列queue.addLast(w);}// 以u为前驱点,访问w的下一个邻接节点w = getNextNeighbor(u, w);}}}// 对bfs进行重载,遍历所有节点public void bfs() {for (int i = 0; i < getnumOfVertexs(); i++) {while (!isVisited[i]) {// 如果没被访问过bfs(isVisited, i);}}}
}
如果要同时显示DFS和BFS遍历结果,需将构造器中的初始化部分摘出来,分别放到DFS和BFS的重载方法里,每次调用时重新分配,就不会出现执行完一种遍历无法执行第二种遍历的情况。
代码如下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;public class graph {private ArrayList<String> vertexList;// 定义顶点列表private int[][] edges;// 存储图对应的邻接矩阵private int numOfEdges;// 存储边private boolean isVisited[];// 标记顶点是否已被访问public static void main(String[] args) {// TODO Auto-generated method stub// 测试图int n = 5;// 定义顶点个数String vertexs[] = { "A", "B", "C", "D", "E" };// 创建图对象graph graph = new graph(n);// 循环添加顶点for (String vertex : vertexs) {// 每次循环从vertexValue取出来一个值(定义为value)graph.insertVertex(vertex);// 把顶点加进去}// 添加边// A-B A-C B-C B-D B-E// 权值默认为是1graph.insertEdges(0, 1, 1);// A-Bgraph.insertEdges(0, 2, 1);// A-Cgraph.insertEdges(1, 2, 1);// B-Cgraph.insertEdges(1, 3, 1);// B-Dgraph.insertEdges(1, 4, 1);// B-E// 显示邻接矩阵graph.show();// DFSSystem.out.println();System.out.println("DFS:");graph.dfs();System.out.println();System.out.println();System.out.println("BFS:");graph.bfs();}// ————————————--------------------------------------------------------// 首先定义图的属性// 1.构造器public graph(int n) {// 首先要传入顶点的数目// 初始化矩阵和vertexListedges = new int[n][n];vertexList = new ArrayList<String>();// 初始化顶点列表numOfEdges = 0;// 可省略,因为默认为0}// 2.插入顶点public void insertVertex(String vertex) {vertexList.add(vertex);}// 3.设置边/*** * @param v1 第一个顶点的下标* @param v2 第二个顶点的下标* @param weight 权值*/public void insertEdges(int v1, int v2, int weight) {// 这里是定义无向图,所以两个方向都要定义edges[v1][v2] = weight;edges[v2][v1] = weight;numOfEdges++;}// 4.返回顶点个数public int getnumOfVertexs() {return vertexList.size();}// 5.返回边个数public int getnumOfEdges() {return numOfEdges;}// 6.返回顶点i(顶点的下标)的对应的数据/*** * @param i返回数据下标* @return 返回数据 例:0->A 1->B 2->C 3->D 4->E*/public String getValueByIndex(int i) {return vertexList.get(i);}// 7.返回v1,v2两顶点之间的权值public int getWeight(int v1, int v2) {return edges[v1][v2];}// 8.打印邻接矩阵(本质:遍历图)public void show() {for (int[] link : edges) {System.out.println(Arrays.toString(link));}}
//————————————-------------------------------------------------------- // DFS算法步骤// 1.得到第一个邻接节点下标w/*** * @param index* @return 如果存在就返回它的下标,没有就返回-1*/public int getFirstNerghborIndex(int index) {// 传入当前节点的下标indexfor (int w = 0; w < vertexList.size(); w++) {if (edges[index][w] > 0) {// 如果下一个邻接节点存在return w;// 返回它的下标}}return -1;// 没有返回就返回-1}// 2.根据前一个邻接节点的下标来获取下一个邻接节点/*** * @param v1* @param v2* @return*/public int getNextNeighbor(int v1, int v2) {for (int w = v2 + 1; w < vertexList.size(); w++) {if (edges[v1][w] > 0) {return w;}}return -1;}// 3.开始深搜遍历private void dfs(boolean[] isVisited, int i) {// 判断是否遍历过的标记,定义节点下标// 首先访问当前节点,输出System.out.print(getValueByIndex(i) + "->");// 访问过后,要标记节点已访问isVisited[i] = true;// 查找节点i的第一个邻接节点int w = getFirstNerghborIndex(i);while (w != -1) {// 存在if (!isVisited[w]) {// 如果没有被标记过dfs(isVisited, w);// 以w为初始节点重新开始,递归操作dfs}// 如果已经被访问过w = getNextNeighbor(i, w);}}// 对dfs进行重载,遍历所有节点public void dfs() {isVisited = new boolean[5];for (int i = 0; i < getnumOfVertexs(); i++) {while (!isVisited[i]) {// 如果没被访问过dfs(isVisited, i);}}}// ————————————--------------------------------------------------------// BFS算法步骤private void bfs(boolean[] isVisited, int i) {int u;// 初始节点,队头结点int w;// 邻接节点// 使用队列记录访问节点的顺序LinkedList queue = new LinkedList();// 访问节点(输出节点信息)System.out.print(getValueByIndex(i) + "->"); 标记为已访问isVisited[i] = true;// 若已访问,添加节点到队列queue.addLast(i);// 重复操作while (!queue.isEmpty()) {// 如果队列不为空// 取出队列的头节点下标u = (Integer) queue.removeFirst();// 得到第一个邻接节点的下标ww = getFirstNerghborIndex(u);while (w != -1) {// 找到邻接节点// 判断是否访问过if (!isVisited[w]) {// 如果没有访问过System.out.print(getValueByIndex(w) + "->");// 访问isVisited[w] = true;// 标记为已访问// 邻接节点入队列queue.addLast(w);}// 以u为前驱点,访问w的下一个邻接节点w = getNextNeighbor(u, w);}}}// 对bfs进行重载,遍历所有节点public void bfs() {isVisited = new boolean[5];for (int i = 0; i < getnumOfVertexs(); i++) {while (!isVisited[i]) {// 如果没被访问过bfs(isVisited, i);}}}
}
图的遍历(Java)构造器相关推荐
- 【数据结构】图-图的遍历_深度优先遍历(动态图解、c++、java)
文章目录 一.概述 二.深度优先搜索 算法步骤 递归 非递归 图解 BFS树 代码 邻接矩阵实现 邻接表实现 链式前向星实现 三.完整代码 邻接矩阵版 邻接表版 链式前向星版 四.总结 算法复杂度分析 ...
- 图深度优先、广度优先遍历(java)
一.图的遍历 图的遍历,即是对结点的访问.一个图有那么多个结点,如何遍历这些结点,需要特定策略,一般有两种访问策略:(1)深度优先遍历(2)广度优先遍历深度优先遍历基本思想. 二.深度优先遍历 图的深 ...
- Java数据结构与算法:无向图,有向图,带权图,图的遍历,最小生成树
文章目录 无向图 有向图 带权图 图的遍历 广度优先遍历 深度优先遍历 最小生成树 无向图 前面了解到树是有单一根结点的非线性结构,图(graph)也是一种非线性结构,其中的结点可以与许多其他的结点相 ...
- c++ 遍历list_数据结构之图的遍历,一篇文章get全部考点
图的概念 举个例子,假设你的微信朋友圈中有若干好友:张三.李四.王五.赵六.七大姑.八大姨. 而你七大姑的微信号里,又有若干好友:你.八大姨.Jack.Rose. 微信中,许许多多的用户组成了一个多对 ...
- 周报(水管工问题,和图的遍历)
枯木逢春不在茂,年少且惜镜边人 这周继续完成上周么有完成的目标,然后学学java,学学图的遍历,学学浴谷上的题,然后上天. 1.水管工问题 #include<stdio.h> int bo ...
- DFS(深度搜索)无向图遍历(JAVA手把手深入解析)
DFS(深度搜索)无向图遍历(JAVA手把手深入解析) 目录 DFS(深度搜索)无向图遍历(JAVA手把手深入解析) 前言 DFS深度优先 无向图 DFS全局变量定义 1.节点 2.节点数 3.根据图 ...
- 二叉树的层级遍历/锯齿遍历--Java版
二叉树的层级遍历/锯齿遍历--Java版 前言 题目 解题思路/知识点 showCode 创建节点对象 创建树对象 创建测试类 层序遍历 锯齿遍历 题目 解体思路 源码(测试类) 结语 前言 今天在力 ...
- 图的遍历 深度与广度优先遍历
图的遍历 本文作者 Mr.赵 Email: lovelyalan@foxmail.com 原创文章,转载标明作者,部分图片素材来自网络 从图中某一顶点出发遍历图中其余顶点,且使每一个顶点仅被访问一次, ...
- 解题报告:luogu P3916 图的遍历( 缩点 + DFS ? × 思维 + 反向建边 + DFS √ )
题目链接:图的遍历 本题是一个有向图,要求每个点能到达的编号最大的点.由于是有向图,如果直接DFS如果有环就可能忽略一些点,所以我们可以直接缩点 缩点之后 在同一个强联通分量中的点可以相互到达,那么我 ...
最新文章
- dbeaver导出表结构和数据_python中的哈希表数据结构
- 让那些为Webkit优化的网站也能适配IE10(转载)
- java冒泡遍历对象_Java经典排序算法(冒泡、选择、插入)
- 熵值法确定权重(matlab附代码)
- bootstrap table传回的数据后端怎么获取_基于 Spring Cloud 开发的分布式系统,遇到爬虫、接口盗刷怎么办
- Scala Object
- PIE SDK矢量点生成等值线、面
- Learning Data Structure_2_线性表、栈和队列
- 烟花散尽漫说无(參考资料)
- 专业营销手段汇编及研究
- 单片机c语言串口中断函数,12手把手教你学单片机的C语言程序设计_中断服务函数.pdf...
- 禁忌搜索算法求解TSP问题python实现
- python机器人编程教材_python人工智能机器人工具书籍: Learn Robotics Programming(python and Raspberry Pi 3) - 2018...
- kakfa 3.0 创建topic流程(源码)
- c语言将浮点变成字符串,c语言将浮点型数据转换成字符串
- html+JavaScript 实现贪吃蛇程序
- Java如何实现定时任务——从某一天起每天定点执行
- JRebel and XRebel idea热部署插件的使用
- 微信小程序详细图文讲解
- NAND flash和NOR flash 基础知识
热门文章
- getvalue参数计数不匹配_OpenCV开发笔记(六十八):红胖子8分钟带你使用特征点Flann最邻近差值匹配识别...
- html如何将多个复选框组织成一组_[Selenium]18.如何处理一组元素
- 详解C++17下的string_view
- Android开发之虹软人脸识别活体检测SDK包Bitmap转NV21方法
- Android开发之ApiCloud模块开发的注意事项
- matlab第三方控件,第三方控件介绍
- day13 生成器 三元运算 列表解析
- Android Status(状态栏) 着色
- 又一波你可能不知道的 Linux 命令行网络监控工具
- jquery表单数据反序列化为字典