Java数据结构与算法之图及图的遍历

水一篇,注释挺详细

package zzh0420;
import java.util.*;

public class GraphTest {
    public static void main(String[] args) {
        //测试一把bfs
        int n = 5;
        Graph graph = new Graph(n);
        String vertex[] = {"A","B","C","D","E"};
        //将顶点插入到图中
        for(int i = 0;i < n;i++){
            graph.vertexList.add(i,vertex[i]);
        }
        //将边插入到图中
        graph.insertEdges(0,1,1);
        graph.insertEdges(0,2,1);
        graph.insertEdges(1,2,1);
        graph.insertEdges(1,3,1);
        graph.insertEdges(1,4,1);
        //展示一下邻接矩阵标识出来的图
        graph.show();
        //测试dfs
//      System.out.println("深度优先搜索");
//      graph.dfs();
        //测试bfs
        System.out.println("广度优先搜索");
        graph.bfs();
    }
}


class Graph{
    public ArrayList<String> vertexList; //存储顶点集合
    private int[][] edges;  //存储邻接矩阵
    private int numOfEdges;  //表示边的个数
    private boolean isVisited[];//记录某个节点是否被访问
    public Graph(int n){
        isVisited =  new boolean[n];
        vertexList = new ArrayList<>(n);
        edges = new int[n][n];
    }


    //插入顶点
    public void insertVertex(String vertex){
        vertexList.add(vertex);
    }

    //插入边
    public void insertEdges(int v1,int v2,int weight){
        edges[v1][v2] = weight;
        edges[v2][v1] = weight;
        numOfEdges++;
    }

    //显示对应的矩阵
    public void show(){
        for(int[] link : edges){
            System.out.println(Arrays.toString(link));
        }
    }

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

    //返回节点i对应下标的数据
    public String getIndex(int i){
        return vertexList.get(i);
    }

    //得到边的数目
    public int getNumOfEdges(){
        return numOfEdges;
    }

    //得到顶点的数目
    public int getNumOfVertex(){
        return vertexList.size();
    }

    //得到当前顶点的邻接顶点
    public int getNeighbour(int i){
        for(int j = 0;j < vertexList.size();j++){
            if(edges[i][j] > 0){
                return j;
            }
        }
        return -1;
    }

    //得到下一个顶点的邻接顶点
    /**
     *
     * @param i 表示当前顶点
     * @param j 表示当前顶点的邻接顶点
     * @return 返回当前顶点临界顶点的临界顶点
     */
    public int getNextNeighbour(int i,int j){
        for(int a = j + 1;a < vertexList.size();a++){
            if(edges[i][a] > 0){
                return a;
            }
        }
        return -1;
    }


    //深度优先搜索算法
    private void dfs(boolean[] isVisited,int index){
        System.out.print(getIndex(index) + "->");//先输出当前顶点信息
        isVisited[index] = true;//标记当前顶点为已访问
        int w = getNeighbour(index);//获取它的邻接顶点
        while(w != -1){//说明有邻接顶点
            if(!isVisited[w]){//如果该顶点没有被访问过
                dfs(isVisited,w);
            }else{//该顶点被访问过
                w = getNextNeighbour(index,w);
            }
        }
    }

    //重载bfs
    public void dfs(){
        for(int i = 0;i < getNumOfVertex();i++){
            if(!isVisited[i]){
                dfs(isVisited,i);
            }
        }
    }

    //广度优先搜索算法
    private void bfs(boolean[] isVisited,int index){
        System.out.print(getIndex(index) + "->");
        isVisited[index] = true;
        int u;//表示队列头节点对应的下标
        int w;//表示邻接节点
        LinkedList queue = new LinkedList();
        queue.addLast(index);
        while(!queue.isEmpty()) {
            //取出队列的头节点
            u = (Integer) queue.removeFirst();//自动拆箱功能
            //得到第一个邻接点的下标
            w = getNeighbour(u);
            while (w != -1) {
                //是否访问过
                if (!isVisited[w]) {
                    System.out.println(getIndex(w) + "->");
                    //标记为已经访问
                    isVisited[w] = true;
                    //入队列
                    queue.addLast(w);
                }
                //以u为前驱节点,找w后面的下一个邻接节点
                w = getNextNeighbour(u, w);//体现出广度优先
            }
        }
    }

    //重载bfs
    public void bfs(){
        for(int i = 0;i < vertexList.size();i++){
            if(!isVisited[i]){
                bfs(isVisited,i);
            }
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

假若爱有天意

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值