zoukankan      html  css  js  c++  java
  • DFS与BFS



    在看数据结构时发现图的这章没怎么看,赶紧瞅瞅,下面以二叉树为例说明


    1. 树的结构

    为了方便读者查看简洁的DFS和BFS逻辑,这里把树的基本结构统一抽取出来且不讨论树的实现


    // 树的基本结构
    public class Tree {
    
        // 树根
        private Node root;
    
        // 树的节点
        private class Node{
            int value;
            Node left;
            Node right;
            public Node (int value,Node left,Node right){
                this.value = value;
                this.left = left;
                this.right = right;
            }
        }
        
        // 省略各种树内部操作,添加查找删除
    }
    




    2. DFS

    深度优先搜索,从某个初始点出发,首先访问初始点,然后选择一个与该点相邻且没有访问过的点,接着以该相邻点为初始点,重复上述操作,直到所有点都被访问过了,即考虑访问到最深度,然后再回溯


    递归实现

    // 树的DFS日常经常使用,前序遍历即可
    // dfs遍历,前序遍历即这个思想,到了叶子节点才回溯
    public void dfs(){
        dfs(root);
    }
    private void dfs(Node node){
        if(node != null){
            System.out.println(node.value);
            dfs(node.left);
            dfs(node.right);
        }
    }
    

    递归虽然容易实现,但其递归过深容易发生StackOverflowError或OOM


    迭代实现

    // 迭代借用栈来实现,也是前序遍历思想,先访问根打印,然后访问左子树再右子树
    // 具体访问顺序使用栈,这里得先右子树入栈,再左子树入栈
    // 从栈弹出节点时也是先一样,重复上面步骤
    
    public void dfsWithStack(){
    
        // LinkedList继承了Deque-->Queue有栈功能
        // 首先入栈根节点
        LinkedList<Node> list = new LinkedList();
        list.addFirst(root);  // 头插法,速度快
    
        // 栈不空则还有节点没遍历
        while(!list.isEmpty()){
            Node temp = list.removeFirst();  // 头删法
            System.out.println(temp.value);
    
            if (temp.right != null){
                list.addFirst(temp.right);
            }
            if(temp.left != null){
                list.addFirst(temp.left);
            }
        }
    }
    




    3. BFS

    广度优先搜索,从某个节点出发,访问初始节点,接着访问初始节点的所有为未访问过的领接节点,再按照前一步的访问顺序访问每一个未访问过的领接节点,直至所有节点被访问过了


    迭代实现

    // 深度使用栈,而广度使用队列
    // 转换到树中就是层级遍历
    
    public void bfsWithStack(){
        Node node = root;
        if(node == null) return ;
    
        LinkedList<Node> list = new LinkedList();  // 队列
        list.addLast(root);  // 进队
    
        while(!list.isEmpty()){
            Node temp = list.removeFirst();  // 出队
            System.out.println(temp.value);
    
            if(temp.left != null){
                list.addLast(temp.left);  // 进队
            }
            if(temp.right != null){
                list.addLast(temp.right);  // 进队
            }
        }
    }
    




    4. 应用(后期补充)

    BFS:最短链

    DFS:走迷宫



  • 相关阅读:
    javascript base64 encode decode 支持中文
    php laravel v5.1 消息队列
    Linux C语言 取得MTU (最大传输单元)
    javascript 字符串 数字反转 字母大小写互换
    为Python安装Redis库
    php 日期相关的类 DateInterval DateTimeZone DatePeriod
    php安全 过滤、验证、转义
    python学习笔记之---多种方式实现list去重
    Python函数重载机制?
    说说下面几个概念:同步,异步,阻塞,非阻塞?
  • 原文地址:https://www.cnblogs.com/Howlet/p/12711633.html
Copyright © 2011-2022 走看看