图的搜索(深度优先)

一:图的搜索

是指从一个指定顶点可以到达哪些顶点

二:搜索的分类

1.深度优先 DFS

图1

2.广度优先 BFS

图2

三:深度优先搜索规则

1.如果可能,访问一个邻接的未访问的顶点,标记它,并把它放进栈中
2.当不能执行规则1的时候,如果栈不能为空,就从栈中弹出一个顶点
3.当不能执行规则1和规则2的时候,就完成了整个搜索过程
图3

四:深度优先代码实现

1.创建栈
public class Stack {
    //栈的底层实现是数组
    long[] arr ;
    //表示栈顶索引
    int top;

    //构造方法
    public Stack(){
        arr = new long[10];
        top = -1;  //初始化栈顶没有数据
    }
    public Stack(int length){
        arr = new long[length];
        top = -1;
    }

    //添加数据--压栈
    public void push(long value){
        arr[++top] = value;
    }

    //删除数据--弹栈
    public long pop(){
        return arr[top--];  //弹栈后数组长度减少
    }

    //查看数据
    public long peek(){
        return arr[top];  //查看数据,不会弹出数据
    }

    //判断是否为空
    public boolean isEmpty(){
        return top==-1;  //返回true则为空
    }

    //判断是否满了
    public boolean isFull(){
        return top==arr.length-1;  //top和数组长度减1 是否相等
    }
}

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 Stack stack;

    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;
        //初始化栈
        stack = new Stack();
    }

    //添加顶点
    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 dfs(){
        //首先访问 0 号顶点
        vertexList[0].wasVisited = true;
        //显示被访问的顶点
        displayVertex(0);
        //进栈,调用压栈方法
        stack.push(0);
        //循环访问顶点,当栈不为空的时候才访问,因为栈为空的时候代表访问完成了
        while (!stack.isEmpty()){
            //获得一个未访问的邻接点
            int v = getVertex((int)stack.peek());
            //找不到的情况
            if (v == -1){
                //弹出顶点
                stack.pop();
            }else{
                //找得到则标记再顶点压栈
                vertexList[v].wasVisited = true;
                //显示
                displayVertex(v);
                stack.push(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.addEdge(0,1);
        graph.addEdge(1,2);
        graph.addEdge(0,3);
        graph.addEdge(3,4);

        //深度优先搜索
        graph.dfs(); //A B C D E
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值