1つの記事でDFS、BFSを理解する

1.深さ優先探索

グラフの深度優先トラバーサルの方法は、グラフの頂点vから開始することです。
(1)頂点vにアクセスし、
(2)vの未アクセスの隣接ポイントから順番に開始し、深度優先トラバーサルを実行します。グラフ;グラフとvまで同じパスの頂点が訪問される;
(3)現時点で訪問されていない頂点がグラフにまだある場合は、訪問されていない頂点から開始し、深さを再実行します-グラフ内のすべての頂点にアクセスするまでの最初のトラバーサル。

最初に二分木を見てください:
ここに画像の説明を挿入

この二分木の場合、深さ優先探索は事前注文トラバーサルです。トラバーサルの結果は次のとおりです。12 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);
    }

main関数で呼び出されます:

    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.幅優先探索

幅優先探索は通常、非再帰形式のキューを採用します。バイナリツリーの場合、幅優先探索はレイヤーシーケンストラバーサルを実現できます。この記事のバイナリツリーを例にとると、レイヤーシーケンストラバーサルの結果は次のようになります。 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
おすすめ