一文弄明白DFS、BFS

1. 深度优先搜索

深度优先遍历图的方法是,从图中某顶点v出发:
(1)访问顶点v;
(2)依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;
(3)若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。

先来看一棵二叉树:
在这里插入图片描述

对于这棵二叉树而言,对它的一个深度优先搜索,就是一次先序遍历:遍历结果是:1 2 4 8 5 3 6 7

在对这个二叉树进行DFS搜索时,我们先来创建一棵这样的二叉树

package test;

public class DFSBinaryTree {
    
    
    public static void main(String[] args) {
    
    
        //创建节点
        Node root=new Node(1);
        Node node2=new Node(2);
        Node node3=new Node(3);
        Node node4=new Node(4);
        Node node5=new Node(5);
        Node node6=new Node(6);
        Node node7=new Node(7);
        Node node8=new Node(8);
        //连接节点
        root.left=node2;
        root.right=node3;
        node2.left=node4;
        node2.right=node5;
        node3.left=node6;
        node3.right=node7;
        node4.left=node8;
        
    }
    
}

class Node{
    
    
    Node left;
    Node right;
    int val;
    public Node(int val)
    {
    
    
        this.val=val;
    }
} 
  • DFS的递归形式
 void DFS(Node root)
    {
    
         
        if(root==null)
          return;
         System.out.print(root.val+"  ");
         DFS(root.left);
         DFS(root.right);
    }

在主函数中调用:

    DFSBinaryTree t=new DFSBinaryTree();
    t.DFS(root);

完整代码:

package test;

public class DFSBinaryTree {
    
    
    public static void main(String[] args) {
    
    
        //创建节点
        Node root=new Node(1);
        Node node2=new Node(2);
        Node node3=new Node(3);
        Node node4=new Node(4);
        Node node5=new Node(5);
        Node node6=new Node(6);
        Node node7=new Node(7);
        Node node8=new Node(8);
        //连接节点
        root.left=node2;
        root.right=node3;
        node2.left=node4;
        node2.right=node5;
        node3.left=node6;
        node3.right=node7;
        node4.left=node8;

        DFSBinaryTree t=new DFSBinaryTree();
        t.DFS(root);
        
    }
     void DFS(Node root)
    {
    
         
        if(root==null)
          return;
         System.out.print(root.val+"  ");
         DFS(root.left);
         DFS(root.right);
    }
    
}

class Node{
    
    
    Node left;
    Node right;
    int val;
    public Node(int val)
    {
    
    
        this.val=val;
    }
}

在这里插入图片描述可以看到输出结果和我们之前写的前序遍历结果是一样的

  • DFS的非递归形式

DFS的非递归形式要采用栈,第一次先把根节点压进栈,然后再压右子节点,是右子节点,然后再压左子节点,然后不断的压栈,出栈访问

 void DFSNotRecursive(Node root)
    {
    
    
        Stack<Node> st=new Stack<>();
        st.push(root);
        while(!st.isEmpty())
        {
    
    
            Node top=st.pop();//获取栈顶节点
            System.out.print(top.val+"  ");

            if(top.right!=null)//先压右子节点
             st.push(top.right);


            if(top.left!=null)
               st.push(top.left);

        }
    }
    

在这里插入图片描述结果和递归形式的DFS一致

2.广度优先搜索

广度优先搜索一般采用队列形式的非递归形式,对于一棵二叉树而言,广度优先搜索可以实现层序遍历,以本文的二叉树为例,层序遍历的结果应该是:1 2 3 4 5 6 7 8

void BFS(Node root)
    {
    
    
        Queue<Node> q=new LinkedList<>();
        q.offer(root);//将节点添加到队尾
        while(!q.isEmpty())
        {
    
    
            Node cur=q.poll();//获取队首节点并将其移除队列
            System.out.print(cur.val+"  ");
            if(cur.left!=null)
               q.offer(cur.left);

            if(cur.right!=null)
               q.offer(cur.right);
            

        }
    }

在这里插入图片描述
全文代码:

package test;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class DFSBinaryTree {
    
    
    public static void main(String[] args) {
    
    
        //创建节点
        Node root=new Node(1);
        Node node2=new Node(2);
        Node node3=new Node(3);
        Node node4=new Node(4);
        Node node5=new Node(5);
        Node node6=new Node(6);
        Node node7=new Node(7);
        Node node8=new Node(8);
        //连接节点
        root.left=node2;
        root.right=node3;
        node2.left=node4;
        node2.right=node5;
        node3.left=node6;
        node3.right=node7;
        node4.left=node8;

        DFSBinaryTree t=new DFSBinaryTree();
        t.DFS(root);
        System.out.println();
        t.DFSNotRecursive(root);

        System.out.println();
        t.BFS(root);
        
    }
     void DFS(Node root)
    {
    
         
        if(root==null)
          return;
         System.out.print(root.val+"  ");
         DFS(root.left);
         DFS(root.right);
    }

    void DFSNotRecursive(Node root)
    {
    
    
        Stack<Node> st=new Stack<>();
        st.push(root);
        while(!st.isEmpty())
        {
    
    
            Node top=st.pop();//获取栈顶节点
            System.out.print(top.val+"  ");

            if(top.right!=null)//先压右子节点
             st.push(top.right);


            if(top.left!=null)
               st.push(top.left);



        }
       
    }
    void BFS(Node root)
    {
    
    
        Queue<Node> q=new LinkedList<>();
        q.offer(root);//将节点添加到队尾
        while(!q.isEmpty())
        {
    
    
            Node cur=q.poll();//获取队首节点并将其移除队列
            System.out.print(cur.val+"  ");
            if(cur.left!=null)
               q.offer(cur.left);

            if(cur.right!=null)
               q.offer(cur.right);
            

        }
    }
    
}

class Node{
    
    
    Node left;
    Node right;
    int val;
    public Node(int val)
    {
    
    
        this.val=val;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_43478694/article/details/114978649