深度优先和广度优先算法

package graph;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;

public class Graph {
    private ArrayList<String>  vertexList;//存储顶点集合
    private int[][] edges;//存储图对应的邻接矩阵
    private int numOfEdges;//表示边的个数
    //定义数组boolean[],记录某个节点是否被访问过
    private boolean[] isVisited;
    public  static  void main(String[] args) {
        //测试图是否创建ok
        int n=5;//节点的个数
        String VertexValue[]={"A","B","C","D","E"};
      //  String VertexValue[]={"1","2","3","4","5","6","7","8"};
        //创建图对象
       Graph graph=   new Graph(n);
       //循环的添加节点
        for(String value:VertexValue)
        {
            graph.insertVertex(value);
        }
        //添加边
        //A-B A-C B-C B-D  B-E
        graph.insertEdge(0,1,1);
        graph.insertEdge(0,2,1);
        graph.insertEdge(1,2,1);
        graph.insertEdge(1,3,1);
        graph.insertEdge(1,4,1);

        //显示一把邻接矩阵
        graph.showGraph();

        //测试一把dfs 是否ok
      //  System.out.println("深度遍历");
      //  graph.dfs();

        //测试一把bfs
        System.out.println("广度优先");
        graph.bfs();
    }

    //构造器
    public  Graph(int n) {
       //初始化矩阵和ArrayList
        edges=new int[n][n];
        vertexList=new ArrayList<String>(n);
        numOfEdges=0;
        isVisited=new boolean[n];
    }
    //得到第一个邻接节点的下标w
    /**
     *
     * @param index
     * @return 如果存在就返回对应的下标 否则返回-1
     */
    public  int getFirstNeighbor(int index)
    {
       for(int j=0;j<vertexList.size();j++)
       {
           if(edges[index][j]>0)
           {
               return j;
           }
       }
       return -1;
    }
    //深度优先遍历算法
    //i 第一次就是0
    public void dfs(boolean[] isVisited,int i)
    {
           //首先我们访问该节点
        System.out.println(getValueByIndex(i)+"->");
        //将该节点设置为已经访问过
        isVisited[i]=true;
        //查找i的第一个邻接节点w
        int w=getFirstNeighbor(i);
        while (w!=-1)
        {
            //说明有
            if(!isVisited[w])
            {
                dfs(isVisited,w);
            }
            //如果w节点已经被访问过
            w=getNextNeighbor(i,w);
        }
    }
    //对dfs 进行重载,遍历所有的节点,并进行dfs
    public void dfs()
    {
        //遍历所有的节点,进行dfs[回溯]
        for(int i=0;i<getNumOfVertex();i++)
        {
            if(!isVisited[i])
            {
                dfs(isVisited,i);
            }
        }
    }

    //根据前一个邻接节点的下标 来获取下一个邻接节点
    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;
    }

    //对一个节点进行广度优先遍历的方法
    private void bfs(boolean[] isVisited,int i)
    {
        int u;//表示队列的头节点对应的下标
        int w;//邻接节点w
        //队列,记录节点访问的顺序
        LinkedList queue=new LinkedList();
        //访问节点,输出节点的信息
        System.out.println(getValueByIndex(i)+"->");
        //标记为已访问
        isVisited[i]=true;
        //将节点加入队列
        queue.addLast(i);
        while (!queue.isEmpty())
        {
            //取出队列的头节点下标
             u=   (Integer) queue.removeFirst();
             //得到第一个邻接点的下标w
             w=getFirstNeighbor(u);
             while (w!=-1)
             {
                 //找到
                 //是否访问过
                 if(!isVisited[w])
                 {
                     System.out.println(getValueByIndex(w)+"->");
                     //标记已经访问
                     isVisited[w]=true;
                     //入队
                     queue.addLast(w);
                 }
                 //以U为前驱点,找w后面的下一个邻接点
                 w=getNextNeighbor(u,w);//体现出我们的广度优先
             }
        }

    }
    //遍历所有的节点,都进行广度优先搜索
    public void bfs()
    {
        for(int i=0;i<getNumOfVertex();i++)
        {
            if(!isVisited[i])
            {
                bfs(isVisited,i);
            }
        }
    }
    //图中常用的方法
    //返回节点的个数
    public int getNumOfVertex()
    {
        return vertexList.size();
    }
    //得到边的数目
    public int getNumOfEdges()
    {
        return numOfEdges;
    }
    //
    //插入节点
    public void insertVertex(String vertex)
    {
        vertexList.add(vertex);
    }
    //返回节点i(下标)对应的数据0->"A"   1->"B"
    public String getValueByIndex(int i)
    {
        return vertexList.get(i);
    }
    //返回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));
        }
    }
    /**
     *
     * @param v1 表示点的下标即是第几个顶点 “A”-“B”,“A”-0,“B”-1
     * @param v2  第二个顶点对应的下标
     * @param weight
     */
    //添加边
    public void insertEdge(int v1,int v2,int weight)
    {
         edges[v1][v2]=weight;
         edges[v2][v1]=weight;
         numOfEdges++;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值