图的广度优先遍历

本文介绍了一种基于邻接矩阵表示的图数据结构,并通过Java代码实现了图的深度优先遍历(DFS)和广度优先遍历(BFS)。通过实例展示了如何添加顶点和边,以及遍历图的过程。
代码
public class Main {
    //用集合存储各个顶点
    static ArrayList<String> vertexList;
    //用二维数组存储各个边(邻接矩阵)
    static int[][] edges;
    //保存边的数目
    static int numOfEdges = 0;
    //表示此顶点有没有被访问到
    static boolean[] isVisited;

    public static void main(String[] args) {
        String[] vertexs = {"A","B","C","D","E"};

        createGraph(5);

        for (int i = 0;i < vertexs.length;i++){
            insertVertex(vertexs[i]);
        }

        insertEdge(0,1,1);
        insertEdge(0,2,1);
        insertEdge(1,2,1);
        insertEdge(1,3,1);
        insertEdge(1,4,1);
        show();
        bfs();
    }
    //得到当前顶点的第一个邻接点
    public static int getFirstNeighber(int cur){
        for (int i = 0;i < vertexList.size();i++){
            if (edges[cur][i] > 0){
                //说明找到了邻接点  判断此点是否已被访问过了
                if (!isVisited[i]){
                    //没被访问过
                    return i;
                }
            }
        }

        return -1;
    }

    //根据当前顶点的某一个邻接点找到下一个邻接点
    public static int getNextNerghber(int cur,int last){
        for (int i = last + 1;i < vertexList.size();i++){
            if (edges[cur][i] > 0){
                if (!isVisited[i]){
                    return i;
                }
            }
        }

        return -1;
    }

    //深度优先遍历

    /**
     *
     * @param isVisited 就是那个boolean数组
     * @param cur  表示遍历到的节点的下标 这里是A B C D E  下标就分别是 0 1 2 3 4
     */
    public static void dfs(boolean[] isVisited,int cur){
        if (!isVisited[cur]){
            //System.out.println("cur 为:"+cur);
            //如果没被访问过
            System.out.println(vertexList.get(cur));
            isVisited[cur] = true;
        }

        //然后找到他的第一个没有被访问过的邻接点
        int neighberIndex = getFirstNeighber(cur);
        while (neighberIndex != -1){
            dfs(isVisited,neighberIndex);

            neighberIndex = getNextNerghber(cur,neighberIndex);
        }
    }

    //广度优先遍历
    //我觉得区别就是体现在 没有递归
    public static void bfs(boolean[] isVisited,int cur){
        //创建队列 保存已被访问到的节点
        LinkedList<Integer> queue = new LinkedList<>();

        if (!isVisited[cur]){
            System.out.println(vertexList.get(cur));
            isVisited[cur] = true;
            //将该点加入队列
            queue.addLast(cur);
        }

        //当队列不为空的时候
        while (!queue.isEmpty()){
            cur = queue.removeFirst();

            //找到cur的第一个邻接点
            int neighberIndex = getFirstNeighber(cur);
            while (neighberIndex != -1){
                if (!isVisited[neighberIndex]){
                    System.out.println(vertexList.get(neighberIndex));
                    isVisited[neighberIndex] = true;
                    //将该点加入队列
                    queue.addLast(neighberIndex);
                }

                neighberIndex = getNextNerghber(cur,neighberIndex);
            }
        }
    }

    public static void bfs(){
        for (int i = 0;i < vertexList.size();i++){
            bfs(isVisited,i);
        }
    }

    //需要重载dfs  针对非连通图
    public static void dfs(){
        for (int i = 0;i < vertexList.size();i++){
            if (!isVisited[i]){
                dfs(isVisited,i);//连通图的画  只需要执行一次就可遍历所有的了 后面都是无效遍历
            }
        }
    }
    //初始化图
    public static void createGraph(int edgeNums){
        vertexList = new ArrayList<String>();
        edges = new int[edgeNums][edgeNums];
        numOfEdges = edgeNums;
        isVisited = new boolean[5];
    }

    //添加顶点
    public static void insertVertex(String oneVertex){
        vertexList.add(oneVertex);
    }

    //添加边
    public static void insertEdge(int v1,int v2,int weight){
        edges[v1][v2] = weight;
        edges[v2][v1] = weight;
        numOfEdges++;
    }

    //返回节点的数目
    public static int getNumOfVertex(){
        return vertexList.size();
    }

    //返回边的数目
    public static int getNumOfEdges(){
        return numOfEdges;
    }

    //返回下标为i的点的数据
    public static String getValueByIndex(int index){
        return vertexList.get(index);
    }

    //返回某一边的权值
    public static int getWeightByV1V2(int v1,int v2){
        return edges[v1][v2];
    }

    public static void show(){
        for (int[] temp: edges){
            System.out.println(Arrays.toString(temp));
        }
    }
}
结果
[0, 1, 1, 0, 0]
[1, 0, 1, 1, 1]
[1, 1, 0, 0, 0]
[0, 1, 0, 0, 0]
[0, 1, 0, 0, 0]
A
B
C
D
E
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值