1.图的深度优先遍历:是先遍历第一个邻结点,然后以第一个邻结点为参考系,递归遍历第一个邻节点的邻节点。
2.图的广度优先遍历是先遍历一个节点所有相邻节点,再遍历第一个相邻节点的所有相邻节点,以此类推,需要借助栈来进行操作。
public class Graph {
private ArrayList<String> vertexList;//存储顶点的集合
private int[][] edges;//存储图对应的临接矩阵
private int numsEdges;//边的个数
private boolean[] isVisit;//是否被访问
public static void main(String[] args) {
int n = 5;//图有5个顶点
String[] Vertexs = {"A","B","C","D","E"};//顶点数组
Graph graph = new Graph(n);
for(String vertex:Vertexs){
graph.insertVertex(vertex);//将顶点插入到图中
}
//构建边的关系
// A-B A-C B-C B-D B-E
graph.addEdge(0,1,1);
graph.addEdge(0,2,1);
graph.addEdge(1,2,1);
graph.addEdge(1,3,1);
graph.addEdge(1,4,1);
graph.show();
// System.out.println("深度优先遍历");
// graph.DFS();
System.out.println("广度优先遍历");
graph.BFS();
}
//构造器
public Graph(int n){
edges = new int[n][n];
vertexList = new ArrayList<String>(n);
numsEdges = 0;
isVisit = new boolean[n];
}
/**
* 广度优先遍历
* @param isVisit
* @param i
*/
private void BFS(boolean[] isVisit,int i){
int u;//表示队列头节点对应的下标
int w;//表示下一个节点的下边
//定义一个栈,定义节点访问的顺序
Stack<Integer> stack = new Stack<>();
//输出当前节点
System.out.println(vertexList.get(i)+"=>");
//标记为以访问
isVisit[i] = true;
//将当前节点入栈
stack.push(i);
while(!stack.empty()){
u = stack.pop();//弹出头节点
//查找u节点的所有邻接节点
w = getFirstNeighbor(u);
while (w!=-1){
if(!isVisit[w]) {
System.out.println(vertexList.get(w) + "=>");
stack.push(w);
isVisit[w] = true;
}
w = getNextNeighbor(u,w);
}
}
}
//遍历所有节点
public void BFS(){
for(int i = 0;i<vertexList.size();i++){
if(!isVisit[i]){
BFS(isVisit,i);
}
}
}
/**
* 深度优先遍历算法
* @param isVisit 是否访问标识
* @param i 当前访问节点下标,第一次是0
*/
private void DFS(boolean[] isVisit,int i){
//首先输出当前节点
System.out.println(getValue(i)+"==>");
//将当前节点置为已访问
isVisit[i] = true;
//获取当前节点的第一个邻接节点
int first = getFirstNeighbor(i);
while(first != -1){
if(!isVisit[first]){
DFS(isVisit,first);
}else {
first = getNextNeighbor(i,first);
}
}
}
//遍历所有节点
public void DFS(){
for(int i = 0;i<vertexList.size();i++){
if(!isVisit[i]){
DFS(isVisit,i);
}
}
}
//返回节点的第一个邻接节点
public int getFirstNeighbor(int index){
for(int j = 0;j<vertexList.size();j++){
if(edges[index][j] > 0){
return j;
}
}
return -1;
}
//根据前一个邻接节点的下标来获取下一个邻接节点
public int getNextNeighbor(int v1,int v2){
for(int j = v2 + 1;j<vertexList.size();j++){
if(edges[v1][j] > 0){
return j;
}
}
return -1;
}
//图常用的方法
//返回节点的个数
public int getNums(){
return vertexList.size();
}
//得到边的个数
public int getEdgs(){
return numsEdges;
}
//返回节点下标对应的数据
public String getValue(int i){
return vertexList.get(i);
}
//返回v1,v2的权值
public int getWeight(int v1,int v2){
return edges[v1][v2];
}
//显示图对应的矩阵
public void show(){
for(int link[]:edges){
System.out.println(Arrays.toString(link));
}
}
//插入节点
public void insertVertex(String vertex){
vertexList.add(vertex);
}
//添加边
/**
*
* @param v1 表示顶点的下标
* @param v2 表示顶点的下标
* @param weight 表示0或者1
*/
public void addEdge(int v1,int v2,int weight){
edges[v1][v2] = weight;
edges[v2][v1] = weight;
numsEdges++;
}
}
来源:CSDN
作者:疯狂的小蜗
链接:https://blog.csdn.net/weixin_43396422/article/details/103936973