图的搜索(广度优先)

一:广度优先规则

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

二:代码实现

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
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值