**
Java实现数据结构,邻接矩阵实现图,Java实现图的深度、广度优先遍历
目录:
- 前言
- 深度预先遍历 使用递归
- 广度优先遍历 使用循环
前言:
首先这里主要讲Java实现图的深度和广度优先遍历,邻接矩阵实现图。
深度优先和广度优先首先是不难,你之所以会来查找如何实现深度优先和广度优先,我觉得是你的深度广度的逻辑不懂,这里会告诉你深度广度的逻辑是什么。然后用代码于实现。
示例图片
**
深度优先
深度优先顾名思义就是:深是遍历的原则(深就是长驱直入),比如我们从A开始寻找,只要找到A的下一个邻接结点(就是和A相连的结点)就可以,找到的是B,再从B开始找B的下一个邻接结点找到的是C,在从C开始找C的邻接结点,(找过的就不在找),没有找到。这时我们说A的深度优先遍历就结束了,再开始B的深度优先遍历。
深度优先简单来说,就是,长驱直入,不管有几个邻接结点,找到一个就行,找不到就从下一个结点开始深度优先遍历。
代码实现:
/**
*
* @author 楠
*
*/
//图
class graph{
public ArrayList<String> vertex;//存储结点的字符串数组
public int[][] edges;//邻接矩阵
public int numOfEdge;//边的个数
public boolean[] isVisited;//辅助遍历工具,用来判断一个结点是否被访问过
//构造器
public graph(int n) {//初始化图
vertex=new ArrayList<String>(n);
edges=new int[n][n];
numOfEdge=0;
}
//深度优先遍历图
public void dfs() {//对每一个结点都进行深度优先遍历
isVisited=new boolean[vertex.size()];//初始化辅助工具,初始均为未被访问
for(int i=0;i<vertex.size();i++) {
if(isVisited[i]) {//被访问就跳过
continue;
}else {
dfs(i);
}
}
}
private void dfs(int i) {//对结点i进行深度优先遍历
System.out.print(getValueOfVertex(i)+"---");
isVisited[i]=true;
int n=getFirst(i);//查找i的邻接结点
if(n!=-1) {//找到了
dfs(n);
}else {
return;
}
}
/**
*
* @param i 给定结点的下标,
* @return 返回结点i的第一个且没有被访问过的邻接结点,没有返回-1
*/
private int getFirst(int i) {
for(int j=0;j<vertex.size();j++) {
if(edges[i][j]>0&&!isVisited[j]) {
return j;
}
}
return -1;
}
/*
一下都是图的基本操作
*/
//添加结点
public void add(String str) {
vertex.add(str);
}
//添加边
public void addEdges(int a,int b,int value) {
edges[a][b]=value;
edges[b][a]=value;
numOfEdge++;
}
//返回结点的个数
public int getNumOfVertex() {
return vertex.size();
}
//根据结点返回权值
public int getValue(int a,int b) {
return edges[a][b];
}
//显示图对应的矩阵
public void show() {
for(int[] arr:edges) {
System.out.println(Arrays.toString(arr));
}
}
//返回边的数目
public int getNumEdges() {
return numOfEdge;
}
//返回下标对应的结点
public String getValueOfVertex(int a) {
return vertex.get(a);
}
}
广度优先:
广度优先也是顾名思义,横向搜索的广度优先的原则,给一个结点i,找到结点i的所有邻接结点。再从找到的结点当中进行广度优先遍历。
代码实现:
/**
*
* @author 楠
*
*/
//图
class graph{
public ArrayList<String> vertex;//存储结点的字符串数组
public int[][] edges;//邻接矩阵
public int numOfEdge;//边的个数
public boolean[] isVisited;//辅助遍历工具,用来判断一个结点是否被访问过
//构造器
public graph(int n) {//初始化图
vertex=new ArrayList<String>(n);
edges=new int[n][n];
numOfEdge=0;
}
//广度优先遍历图
public void bfs() {//广度优先遍历只从一个遍历一次就可以了
isVisited=new boolean[vertex.size()];
bfs(0);
System.out.println();
}
private void bfs(int i) {
LinkedList<Integer> queue = new LinkedList<Integer>();//队列存储遍历出来的结点
System.out.print(getValueOfVertex(i)+"--");
queue.addLast(i);
isVisited[i]=true;
while (!queue.isEmpty()) {//队列空的时候就遍历完了
int w=queue.removeFirst();
int n=getFirst(w);
while (n!=-1) {//找到所有的邻接结点
queue.addLast(n);
System.out.print(getValueOfVertex(n)+"--");
isVisited[n]=true;
n=getFirst(w);
}
}
}
/**
*
* @param i 给定结点的下标,
* @return 返回结点i的第一个且没有被访问过的邻接结点,没有返回-1
*/
private int getFirst(int i) {
for(int j=0;j<vertex.size();j++) {
if(edges[i][j]>0&&!isVisited[j]) {
return j;
}
}
return -1;
}
/*
一下都是图的基本操作
*/
//添加结点
public void add(String str) {
vertex.add(str);
}
//添加边
public void addEdges(int a,int b,int value) {
edges[a][b]=value;
edges[b][a]=value;
numOfEdge++;
}
//返回结点的个数
public int getNumOfVertex() {
return vertex.size();
}
//根据结点返回权值
public int getValue(int a,int b) {
return edges[a][b];
}
//显示图对应的矩阵
public void show() {
for(int[] arr:edges) {
System.out.println(Arrays.toString(arr));
}
}
//返回边的数目
public int getNumEdges() {
return numOfEdge;
}
//返回下标对应的结点
public String getValueOfVertex(int a) {
return vertex.get(a);
}
}