图(无向连通无权图)-广度优先搜索

public class Queue {
    private final int SIZE=20;//列队数量
    private int [] queArray;//存数据的数组
    private int front ;//用于记录队列的头部(为了删除)
    private int rear;//用于记录队列的尾部(为了增加)
    public Queue() {
        queArray=new int[SIZE];//初始化队列的数据数组
        front =0;//初始化队列的头部
        rear=-1;//初始化队列的尾部
        
    }
    public void insert(int j) {//对尾添加一个元素
        if(rear==SIZE-1)
            rear=-1;//判断如果标记队列尾部的数字等于SIZE-1,说明数组已经满了,从头开始
        queArray[++rear]=j;//存入数据
    }
    public int remove() {//删除数据,并返回
        int temp=queArray[front++]; //获取删除掉的数据
        if(front==SIZE)//判断如果删到了最后一个(意思是删完了,就恢复到最终状态,从头开始)
            front=0;
        return temp;
    }
    public boolean isEmpty() {
        return (rear+1==front);
    }

}
//图的顶点
public class Vertex {
    public char label;//顶点的标识符
    public boolean wasVisited;//顶点有无被访问的标志
    public Vertex(char lab) {//初始化顶点(属性)
        label=lab;
        wasVisited=false;
        
    }
    

}
public class Graph {
    private final int MAX_VERTS=20;//最大顶点数
    private Vertex[] vertexList;//顶点数组
    private int [][]adjMat;//顶点关系的领接矩阵(邻接矩阵的每行或者每列的位置跟顶点数组是对应的)
    private int nVerts;//当前顶点个数
    private Queue theQueue;//列队,用于遍历的工具
    public Graph() {//初始化图
        vertexList=new Vertex[MAX_VERTS]; //初始化顶点数组
        adjMat=new int [MAX_VERTS][MAX_VERTS] ;//初始化邻接矩阵
        for(int j=0;j<MAX_VERTS;j++)
            for(int i=0;i<MAX_VERTS;i++)
                adjMat[i][j]=0;
        nVerts=0;//初始化当前顶点个数
        theQueue=new Queue();//建立列队对象
        
        
    }
    //向顶点数组中添加顶点对象
    public void addVertex(char lab) {
        vertexList[nVerts++]=new Vertex(lab);//建立lab对象,往数组内添加
    }
    //添加边(向邻接矩阵中改变数据为1)
    public void addEdge(int start,int end) {
        //因为是无向图所以(i,j)(j,i)都要添加1
        adjMat[start][end]=1;
        adjMat[end][start]=1;
    }
    //打印顶点数组,根据获取的顶点数组的下标值,打印顶点
    public void displayVertex(int v) {
        System.out.print(vertexList[v].label);
    }

    //广度优先搜索,遍历顶点数组中的每个字符
    public void bfs() {
        vertexList[0].wasVisited=true;//访问第一个顶点
        displayVertex(0);//输出第一个顶点
        theQueue.insert(0);//将第一个顶点的下标放入栈中(遍历的初始化)
        int v2;
        while(!theQueue.isEmpty()) {
            int v1=theQueue.remove();//从队头部取出一个数据
            while((v2=getAdjUnvisitedVertex(v1))!=-1)//取出该顶点的所有邻接顶点
            {
                vertexList[v2].wasVisited=true;
                displayVertex(v2);
                theQueue.insert(v2);
            }
        }
        for(int j=0;j<nVerts;j++)//将定点数组中的顶点状态还原
            vertexList[j].wasVisited=false;
    }
    //返回当前顶点是否有相邻的顶点(只找一个),并且是没有访问过的.找到了就返回顶点的数组下标,没找到就返回-1
    public int getAdjUnvisitedVertex(int v) {//v为顶点数组下标
        for(int j=0;j<nVerts;j++)//遍历邻接矩阵的当前行
            if(adjMat[v][j]==1&&vertexList[j].wasVisited==false)//邻接矩阵的每行每列的位置跟顶点数组是对应的
                //判断某顶点跟当前顶点是否有关系,并且没有访问过的
                return j;
        return -1;
    }
    
  
    
    
    
    
    
    
    
}
public class Test {
    public static void main(String[] agrs) {
        Graph theGraph=new Graph();//创建一个图
        theGraph.addVertex('A');//添加顶点
        theGraph.addVertex('B');//添加顶点
        theGraph.addVertex('C');//添加顶点
        theGraph.addVertex('D');//添加顶点
        theGraph.addEdge(0, 1);//添加边
        theGraph.addEdge(0, 2);//添加边
        theGraph.addEdge(0, 3);//添加边
        theGraph.addEdge(1, 3);//添加边
        theGraph.bfs();
        
    }

}

广度优先搜索:是取出和放入的操作。将队列中的一个值删除并取出,若有邻接顶点,则放入所有的顶点入队列。如此循环

posted @ 2017-10-18 15:07  S-Mustard  阅读(460)  评论(0编辑  收藏  举报