这两天学习图论中的广度优先搜索和深度优先搜索。看的有些迷糊就去B站看了视频,当时一键三联非常痛快,后来发现老哥写错了。。。。 现在在他的基础上修改了广度优先算法。因为寻找相邻顶点(包括第一个相邻顶点和后续的顶点)找不到时也需返回值,源代码中返回-1,导致在isVisited数组中出现了index==-1的情况,索性将返回值设为n(顶点个数),并把isVisited数组扩大一位,将isVisited[n]设为false,在后续为队列添加相邻顶点提供判断`
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
public class Graph {
public static void main(String[] args) {
Graph graph = new Graph(6);
graph.addVertax("A");
graph.addVertax("B");
graph.addVertax("C");
graph.addVertax("D");
graph.addVertax("E");
graph.addVertax("F");
graph.addEdges(0,1,1);
graph.addEdges(0,2,1);
graph.addEdges(0,3,1);
graph.addEdges(5,3,1);
graph.addEdges(1,4,1);
graph.addEdges(2,4,1);
graph.addEdges(3,4,1);
showEdges();
graph.dfs();
}
//这里是定点数n,顶点集合Vertax,边的集合edges,是否被访问过得标记符isvisited
private int n;
private int numberOfEdges;
private ArrayList<String> Vertax;
private static int[][] edges;
private boolean[] isVisited;
public Graph(int n){
this.n = n;
numberOfEdges=0;
Vertax = new ArrayList<>(n);
edges = new int[n][n];
isVisited = new boolean[n+1];
}
//打印邻接表
public static void showEdges(){
for (int[] edse: edges
) {
System.out.println(Arrays.toString(edse));
}
}
//获取顶点数
public int GetSizeOfGraph(ArrayList<String> Vertax){
return Vertax.size();
}
//添加顶点
public void addVertax(String s){
Vertax.add(s);
}
//获取指定顶点的第一个相邻顶点
public int getFirstCO(int index){
for (int i = 0; i <Vertax.size() ; i++) {
if (edges[index][i]>0) return i;
}
return n;
}
//获取指定顶点的顺次相邻顶点
public int getNextCO(int index,int firstCO){
for (int i =firstCO+1 ; i <Vertax.size() ; i++) {
if (edges[index][i]>0) return i;
}
return n;
}
//添加边
public void addEdges(int e1,int e2 , int weight){
edges[e1][e2] = weight;
edges[e2][e1] = weight;
numberOfEdges++;
}
//获取边数
public int getNumberOfEdges(){
return numberOfEdges;
}
//深度优先搜索,从指定顶点开始深度优先搜索
public void dfs(boolean[] isVisited, int i){
System.out.println(Vertax.get(i));
isVisited[i] = true;
int CO = getFirstCO(i);
while (CO!=n){
if (!isVisited[CO]){
dfs(isVisited,CO);
}
CO = getNextCO(i,CO);
}
}
//指定开始顶点进行深度优先搜索,当搜索结束时查看有无重载需要
public void dfs(){
//int timeOfReload =1;
for (int i = 0; i <Vertax.size() ; i++) {
if (!isVisited[i]){
dfs(isVisited,i);
//timeOfReload++;
}
}
//System.out.println(timeOfReload);
}
public void bfs(){
for (int i = 0; i <Vertax.size() ; i++) {
if (!isVisited[i]){
bfs(isVisited,i);
}
}
}
public void bfs(boolean[] isVisited,int index){
//CO 是迭代所需坐标,headIndex为每次广度优先搜索的启动顶点
int CO;
int headIndex = index;
LinkedList<Integer> queue = new LinkedList<>();
//
System.out.println(Vertax.get(index));
isVisited[index]=true;
queue.add(index);
//获取相邻顶点
while (!queue.isEmpty()){
headIndex = queue.removeFirst();
//CO为第一个没被visited的CO
CO = getFirstCO(headIndex);
while(isVisited[CO]){
CO = getNextCO(headIndex,CO);
}
if (CO==n) {}
//把一个顶点的所有相邻顶点加入队列
else {
while (!isVisited[CO]&&CO<n) {
System.out.println(Vertax.get(CO));
isVisited[CO] = true;
queue.add(CO);
CO = getNextCO(headIndex, CO);
}
}
}
}
}