Recherche de site Web

Recherche en profondeur (BFS) et recherche en profondeur (DFS) pour les arbres binaires en Java


La recherche en profondeur d'abord et la recherche en profondeur d'abord sont deux techniques de parcours de graphes et d'arbres. Dans ce tutoriel, nous nous concentrerons principalement sur les traversées BFS et DFS dans les arbres.

Qu'est-ce que la recherche en profondeur (DFS) ?

L'algorithme commence au nœud racine, puis il explore chaque branche avant de revenir en arrière. Il est implémenté à l'aide de piles. Souvent, lors de l'écriture du code, nous utilisons des piles de récursivité pour revenir en arrière. En utilisant la récursivité, nous pouvons tirer parti du fait que les sous-arbres gauche et droit sont également des arbres et partagent les mêmes propriétés.

Pour les arbres binaires, il existe trois types de traversées DFS.

  1. En ordre
  2. Pré-commande
  3. Post-commande

Qu'est-ce que la recherche en largeur (BFS) ?

Cet algorithme commence également au nœud racine, puis visite tous les nœuds niveau par niveau. Cela signifie qu'après la racine, il traverse tous les enfants directs de la racine. Une fois que tous les enfants directs de la racine ont été parcourus, elle se déplace vers leurs enfants et ainsi de suite. Pour implémenter BFS, nous utilisons une file d'attente.

Pour les arbres binaires, nous avons Level Order Traversal qui suit BFS.

Implémentation de BFS et DFS en Java

Soit l'arbre considéré :

La structure de la classe TreeNode est la suivante :

 static class TreeNode {
        int data;
        TreeNode left, right;

        public TreeNode(int key) {
            data = key;
            left = right = null;
        }
    }

1. Traversée de pré-commande

Dans le parcours pré-ordonné d'un arbre binaire, nous parcourons d'abord la racine, puis le sous-arbre gauche et enfin le sous-arbre droit. Nous le faisons de manière récursive pour bénéficier du fait que les sous-arbres gauche et droit sont également des arbres.

L'algorithme de parcours de pré-ordre est le suivant :

  1. Traverser la racine.
  2. Appelez preorder() dans la sous-arborescence de gauche.
  3. Appelez preorder() dans la sous-arborescence de droite.

La traversée de pré-commande de l'arbre ci-dessus est :

0 1 3 4 2 

Le code java est le suivant :

 static void preorder(TreeNode TreeNode) {
        if (TreeNode == null)
            return;

        // Traverse root
        System.out.print(TreeNode.item + "->");
        // Traverse left
        preorder(TreeNode.left);
        // Traverse right
        preorder(TreeNode.right);
    }

2. Traversée dans l'ordre

Le parcours dans l'ordre d'un arbre binaire traverse d'abord le sous-arbre gauche, puis la racine et enfin le sous-arbre droit.

L'algorithme de parcours dans l'ordre est le suivant :

  1. Appelez inorder() sur le sous-arbre de gauche.
  2. Traverser la racine.
  3. Appelez inorder() sur le sous-arbre de droite.

Le parcours dans l'ordre de l'arbre ci-dessus est :

3 1 4 0 2 

Le code java est le suivant :

 static void inorder(TreeNode TreeNode) {
        if (TreeNode == null)
            return;

        // Traverse left
        inorder(TreeNode.left);
        // Traverse root
        System.out.print(TreeNode.item + "->");
        // Traverse right
        inorder(TreeNode.right);
    }

3. Traversée post-commande

Le parcours post-ordre d'un arbre binaire traverse d'abord le sous-arbre gauche puis le sous-arbre droit et enfin la racine.

L'algorithme de parcours post-ordre est le suivant :

  1. Appelez postorder() sur le sous-arbre de gauche.
  2. Appelez postorder() sur le sous-arbre de droite.
  3. Traverser la racine.

Le parcours post-ordre de l'arbre ci-dessus est :

3 4 1 2 0 

Le code java est le suivant :

 static void postorder(TreeNode TreeNode) {
        if (TreeNode == null)
            return;

        // Traverse left
        postorder(TreeNode.left);
        // Traverse right
        postorder(TreeNode.right);
        // Traverse root
        System.out.print(TreeNode.item + "->");
    }

4. Traversée d'ordre de niveau

La traversée d'ordre de niveau utilise une file d'attente pour garder une trace des nœuds à visiter. Après avoir visité un nœud, ses enfants sont placés dans la file d'attente. Pour obtenir un nouveau nœud à traverser, nous retirons des éléments de la file d'attente.

L'algorithme est le suivant :

  1. Initialiser une file d'attente vide
  2. Commencez par définir temp en tant que racine
  3. Exécuter une boucle jusqu'à ce que la file d'attente ne soit pas vide
    1. Imprimer les données de temp.
    2. Mettre en file d'attente les enfants de temp dans l'ordre de gauche puis de droite.
    3. Retirer un nœud de la file d'attente et attribuer sa valeur à temp.

    Le parcours d'ordre de niveau de l'arbre ci-dessus est :

    0 1 2 3 4
    

    Le code java est le suivant :

     static void printLevelOrder(TreeNode root) {
           Queue<TreeNode> queue = new LinkedList<TreeNode>();
           queue.add(root);
           while (!queue.isEmpty()) {
               TreeNode temp = queue.poll();
               System.out.print(temp.data + " ");
    
               /*add left child to the queue */
               if (temp.left != null) {
                   queue.add(temp.left);
               }
    
               /*add right right child to the queue */
               if (temp.right != null) {
                   queue.add(temp.right);
               }
           }
       }
    

    Implémentation complète du code de BFS et DFS en Java

    Le code Java complet est donné ci-dessous :

    package com.JournalDev;
    import java.util.LinkedList;
    import java.util.Queue;
    
    public class Main {
        static class TreeNode {
            int data;
            TreeNode left, right;
    
            public TreeNode(int key) {
                data = key;
                left = right = null;
            }
        }
    
        static void preorder(TreeNode TreeNode) {
            if (TreeNode == null)
                return;
    
            // Traverse root
            System.out.print(TreeNode.data + " ");
            // Traverse left
            preorder(TreeNode.left);
            // Traverse right
            preorder(TreeNode.right);
        }
    
        static void inorder(TreeNode TreeNode) {
            if (TreeNode == null)
                return;
    
            // Traverse left
            inorder(TreeNode.left);
            // Traverse root
            System.out.print(TreeNode.data + " ");
            // Traverse right
            inorder(TreeNode.right);
        }
    
        static void postorder(TreeNode TreeNode) {
            if (TreeNode == null)
                return;
    
            // Traverse left
            postorder(TreeNode.left);
            // Traverse right
            postorder(TreeNode.right);
            // Traverse root
            System.out.print(TreeNode.data + " ");
        }
       static void printLevelOrder(TreeNode root) {
           Queue<TreeNode> queue = new LinkedList<TreeNode>();
           queue.add(root);
           while (!queue.isEmpty()) {
               TreeNode tempNode = queue.poll();
               System.out.print(tempNode.data + " ");
    
               /*add left child to the queue */
               if (tempNode.left != null) {
                   queue.add(tempNode.left);
               }
    
               /*add right right child to the queue */
               if (tempNode.right != null) {
                   queue.add(tempNode.right);
               }
           }
       }
    
        public static void main(String args[])
                
        {
            TreeNode root = new TreeNode(0);
            root.left = new TreeNode(1);
            root.right = new TreeNode(2);
            root.left.left = new TreeNode(3);
            root.left.right = new TreeNode(4);
            System.out.println("Inorder traversal");
            inorder(root);
    
            System.out.println("\nPreorder traversal ");
            preorder(root);
    
            System.out.println("\nPostorder traversal");
           postorder(root);
    
            System.out.println("\nLevelorder traversal");
            printLevelOrder(root);
    
        }
    
    } 
    
    
    Output : 
    
    Inorder traversal
    3 1 4 0 2 
    Preorder traversal 
    0 1 3 4 2 
    Postorder traversal
    3 4 1 2 0 
    Levelorder traversal
    0 1 2 3 4 
    
    

    Conclusion

    Ce tutoriel concernait les traversées BFS et DFS dans les arbres binaires. Pour obtenir l'implémentation DFS en C++, reportez-vous à ce tutoriel.

Articles connexes: