欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

图的搜索(广度优先)

程序员文章站 2022-06-12 19:11:16
...

一:广度优先规则

1.访问下一个邻接的未访问过的顶点,这个顶点必须是当前顶点的邻接点,标记他,并把它插入到队列中
2.如果无法执行规则1,那么就从队列头取出一个顶点,并使其作为当前顶点
3.当队列为空不能执行规则2时,就是搜索完成时.
图的搜索(广度优先)

二:代码实现

1.创建队列

public class Quene {
    //队列底层也是数组
    long[] arr;
    //队列长度
    int length;
    //队头
    int front;
    //队尾
    int end;

    //构造方法
    public Quene(){
        arr = new long[10];
        length=0;
        front=0;
        end=-1;
    }
    public Quene(int size){
        arr = new long[size];
        length=0;
        front=0;
        end=-1;
    }

    //1.添加数据,从队列尾插入
    public void insert(long value){
        arr[++end] = value;
        length++;
    }

    //2.删除数据,从队头开始
    public long romove(){
        length--;            //长度减减
        return arr[front++]; //把第一个数据移除,队头就会++
    }

    //3.查看数据,从队头查看
    public long peek(){
        return arr[front];
    }

    //4.判断是否为空
    public boolean isEmpty(){
        return length==0;
    }

    //5.判断是否满了
    public boolean isFull(){
        return length == arr.length;
    }
}

2.创建顶点

//顶点类
public class Vertex {
    //顶点名称
    public char label;
    //添加是否被访问属性
    public boolean wasVisited;

    public Vertex( char label){
        this.label = label;
    }
}

3.创建图

//图
public class Graph {
    //顶点数组
    private Vertex[] vertexList;
    //邻接矩阵,二维数组
    private int[][] arr;
    //顶点最大数量
    private int maxSize = 20;
    //已添加顶点数量
    private int vt;
    //引入已创建的建栈,用于存储搜索的数据
    private Quene quene;

    public Graph(){
        //初始化顶点数组
        vertexList = new Vertex[maxSize];
        //初始化邻接矩阵
        arr = new int[maxSize][maxSize];
        //初始化值
        for (int i= 0;i<maxSize;i++){
            for (int j= 0;j<maxSize;j++){
                //代表所有的边都不相连
                arr[i][j] = 0;
            }
        }
        vt = 0;
        //初始化栈
        quene = new Quene();
    }

    //添加顶点
    public void addVertex(char label){
        //往顶点数组内添加顶点
        vertexList[vt++] = new Vertex(label);
    }

    //添加边
    public void addEdge(int start , int end){
        //从 start 到 end 连通
        arr[start][end] = 1;
        //从 end 到 start 自然也连通
        arr[end][start] = 1;
    }

    //查找节点
    //参数 v : 代表从哪个节点开始找(前提是这个节点未被访问过)
    public int getVertex(int v){
        //在邻接矩阵里面找未被访问过的节点
        for (int i = 0; i < vt; i++){
            //判断节点之间是否相邻 同时 是否未被访问
            if (arr[v][i] == 1 && vertexList[i].wasVisited == false){
                //当该v和i节点相邻且i节点未被访问过,则返回
                return i;
            }
        }
        return -1;
    }

    //广度优先搜索
    public void bfs(){
        //首先访问 0 号顶点
        vertexList[0].wasVisited = true;
        //显示被访问的顶点
        displayVertex(0);
        //把0顶点插入队列
        quene.insert(0);

        //循环访问顶点,当队列不为空的时候,取出头节点再插入其邻接点
        while (!quene.isEmpty()){
            //获得队列头节点的一个未访问的邻接点
            int v = getVertex((int)quene.peek());
            //找不到的情况
            if (v == -1){
                //取出队列头节点
                quene.romove();
            }else{
                //找得到则标记再顶点压栈
                vertexList[v].wasVisited = true;
                //显示
                displayVertex(v);
                quene.insert(v);
            }
        }
        //搜索完成后,复原
        for (int i = 0; i < vt ; i++){
            vertexList[i].wasVisited = false;
        }
    }

    //显示
    public void displayVertex(int v){
        System.out.println(vertexList[v].label);
    }
}

4.测试

public class Test {
    public static void main(String[] args) {

        //添加顶点
        Graph graph = new Graph();
        graph.addVertex('A');
        graph.addVertex('B');
        graph.addVertex('C');
        graph.addVertex('D');
        graph.addVertex('E');
        graph.addVertex('F');

        //添加边
        graph.addEdge(0,1);
        graph.addEdge(1,2);
        graph.addEdge(0,3);
        graph.addEdge(3,4);
        graph.addEdge(0,5);

        //广度优先搜索
        graph.bfs(); //A B D F C E
    }
}

相关标签: 数据结构与算法