java实现图的深度优先遍历(dfs)和广度优先遍历(bfs)-------参考视频 韩顺平《java数据结构和算法》

完整代码如下:

package com.wqc.graph;
import java.util.*;

/**
 * @author 高瞻远瞩
 * @version 1.0
 * 演示无向图的创建  ---邻接矩阵   图的深度优先遍历  以及广度优先遍历
 */
public class Graph {
    private ArrayList<String> vertexList;//存储图的结点  用String表示结点
    private int[][] edges;//定义一个二维数组  表示顶点之间的联系 1表示直接相连 0表示没有直达路径
    private int edgeCounts;//表示边的个数
    private boolean[] isVisited;//标记结点是否被访问
    private Queue<Integer> queue;//用来存储刚被标记的结点

    public static void main(String[] args) {
        int n = 5;//定义结点的个数
        String[] vertexList = {"A", "B", "C", "D", "E"};
        Graph graph = new Graph(n);
        for (String vertex : vertexList) {
            graph.addVertex(vertex);//添加顶点到集合
        }
        //添加边到集合
        graph.addEdge(0, 1, 1);//A--B
        graph.addEdge(0, 2, 1);//A--C
        graph.addEdge(1, 2, 1);//B--C
        graph.addEdge(1, 3, 1);//B--D
        graph.addEdge(1, 4, 1);//B--E
        graph.showGraph();
        System.out.print("图的深度优先遍历 ");
        graph.dfs();
        System.out.print("\n图的广度优先遍历 ");
        graph.bfs();
    }

    public Graph(int n) {//初始化二维数组和集合
        vertexList = new ArrayList<>(n);
        edges = new int[n][n];
        isVisited = new boolean[n];
        queue = new LinkedList<>();
    }

    public void bfs() {//遍历所有结点 进行广度优先遍历
        isVisited = new boolean[getNumOfVertex()];
        for (int i = 0; i < getNumOfVertex(); i++) {
            if (!isVisited[i]) {
                bfs(isVisited, i);
            }
        }
    }

    //对一个结点进行广度优先遍历 类似于层次遍历
    public void bfs(boolean[] isVisited, int i) {
        System.out.print(getVertexByIndex(i) + "-->");
        isVisited[i] = true;//标记为已访问
        queue.offer(i);//入队
        int u;//表示队列头节点的下标
        int w;//表示u的邻接点下标
        while (!queue.isEmpty()) {
            u = queue.poll();//出队
            w = getFirstLinkedVertex(u);
            while (w != -1) {//只要还有邻接点 就进行while循环
                if (!isVisited[w]) {
                    System.out.print(getVertexByIndex(w) + "-->");
                    isVisited[w] = true;
                    queue.offer(w);//再入队
                }
                w = getNextVertex(u, w);//找遍以u为结点所有的未被访问的邻接点输出并入队
                //这句话充分体现广度优先遍历
            }
        }
    }

    public void dfs() {//遍历所有结点 进行图的深度优先遍历  考虑到有的结点之间并没有相互联系 所以需要遍历每一个结点进行dfs算法
        isVisited = new boolean[getNumOfVertex()];
        for (int i = 0; i < getNumOfVertex(); i++) {
            if (!isVisited[i]) {
                dfs(isVisited, i);
            }
        }
    }

    //以一个结点开始的的图的深度优先遍历  DFS
    private void dfs(boolean[] isVisited, int i) {
        System.out.print(getVertexByIndex(i) + "-->");//输出
        isVisited[i] = true;//标记为已访问
        int w = getFirstLinkedVertex(i);
        while (w != -1) {//只要以当前结点的索引的第一个邻接点存在 就进行while循环
            if (!isVisited[w]) {//当前结点(递归过程中这个结点在变化)第一个邻接点只要没有被访问 就进行递归访问
                dfs(isVisited, w);
            }
            //如果当前结点的第一个邻接点已经被访问过  就进行以i为索引的结点 获取他的第二个邻接点  即以第一个邻接点的下一个邻接点
            w = getNextVertex(i, w);//直到w=-1 跳出while循环 方法结束
        }
    }

    //获取到当前索引的结点的第一个邻接点索引 如果没有 则返回-1
    public int getFirstLinkedVertex(int index) {
        for (int i = 0; i < edges.length; i++) {
            if (edges[index][i] > 0) {
                return i;
            }
        }
        return -1;
    }

    //获取到当前索引结点v的邻接结点w的下一个邻接结点的索引  如果没有则返回-1
    public int getNextVertex(int v, int w) {
        for (int i = w + 1; i < edges.length; i++) {
            if (edges[v][i] > 0) {
                return i;
            }
        }
        return -1;
    }

    //添加顶点到集合的方法
    public void addVertex(String value) {
        vertexList.add(value);
    }

    /**
     * @param v1     添加的第一个顶点在集合中的下标
     * @param v2     添加的第二个顶点在集合中的下标
     * @param weight 代表是否直接相连
     */
    //添加边到集合的方法
    public void addEdge(int v1, int v2, int weight) {
        edges[v1][v2] = weight;//注意是无向图
        edges[v2][v1] = weight;
        edgeCounts++;
    }

    //查看图中顶点的个数
    public int getNumOfVertex() {
        return vertexList.size();
    }

    //查看边的个数
    public int getEdgeCount() {
        return edgeCounts;
    }

    //根据索引获取到顶点
    public String getVertexByIndex(int index) {
        return vertexList.get(index);
    }

    //返回v1 和 v2 的权值
    public int getWeight(int v1, int v2) {
        return edges[v1][v2];
    }

    //查看图
    public void showGraph() {
        for (int[] link : edges) {
            System.out.println(Arrays.toString(link));
        }
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值