2
votes

Comment pousser les nœuds d'un arbre binaire dans un tableau?

J'ai du mal à pousser les valeurs d'un arbre de recherche binaire dans un tableau, mais j'ai également besoin qu'elles soient triées. Voici les instructions de ce qui est nécessaire.

La méthode toArray doit créer et retourner un tableau contenant chaque élément de l'arborescence dans l'ordre trié ("dans l'ordre"). La capacité de ce tableau doit être égale au nombre d'éléments qu'il contient. Cette méthode doit utiliser la méthode d'assistance privée récursive toArray (BSTNode, List) pour générer le tableau. Ce tableau devra être créé comme un tableau d'objets comparables et converti en un tableau d'objets E. Vous pouvez utiliser la méthode toArray (E []) de Collection pour aider à la génération du tableau.

Voici donc mon code que j'ai jusqu'à présent:

public class BinarySearchTree<E extends Comparable<E>>
{
private BSTNode<E> root; // root of overall tree
private int numElements;

// post: constructs an empty search tree
public BinarySearchTree()
{
    root = null;
}

// post: value added to tree so as to preserve binary search tree
public void add(E value)
{
    root = add(root, value);
}
// post: value added to tree so as to preserve binary search tree
private BSTNode<E> add(BSTNode<E> node, E value)
{
    if (node == null)
    {
        node = new BSTNode<E>(value);
        numElements++;
    }
    else if (node.data.compareTo(value) > 0)
    {
        node.left = add(node.left, value);
    }
    else if (node.data.compareTo(value) < 0)
    {
        node.right = add(node.right, value);
    }
    return node;
}

// post: returns true if tree contains value, returns false otherwise
public boolean contains(E value)
{
    return contains(root, value);
}
// post: returns true if given tree contains value, returns false otherwise
private boolean contains(BSTNode<E> node, E value)
{
    if (node == null)
    {
        return false;
    }
    else
        {
        int compare = value.compareTo(node.data);
        if (compare == 0)
        {
            return true;
        }
        else if (compare < 0)
        {
            return contains(node.left, value);
        }
        else
            {   // compare > 0
            return contains(node.right, value);
        }
    }
}
    public void remove(E value)
    {
        root = remove(root, value);
    }
    private BSTNode<E> remove(BSTNode<E> node, E value)
    {
        if(node == null)
        {
            return null;
        }
        else if(node.data.compareTo(value) < 0)
        {
            node.right = remove(node.right, value);
        }
        else if(node.data.compareTo(value) > 0)
        {
            node.left = remove(node.left, value);
        }
        else
        {
            if(node.right == null)
            {
                numElements--;
                return node.left;// no R child; replace w/ L
            }
            else if(node.left == null)
            {
                numElements--;
                return node.right;   // no L child; replace w/ R
            }
            else
            {
                // both children; replace w/ max from L
                node.data = getMax(node.left);
                node.left = remove(node.left, node.data);
            }
        }
        return node;
    }
    private E getMax(BSTNode<E> node)
    {
        if(node.right == null)
        {
            return node.data;
        }
        else
        {
            return getMax(node.right);
        }
    }
    public void clear()
    {
        root = null;
        numElements--;
    }
    public boolean isEmpty()
    {
        if(numElements == 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public int size()
    {
        return numElements;
    }
    //My toArray Methods will go here. 
    public Iterator<E> iterator()
    {
        return new Iterator<>(root);
    }
    public static class Iterator<E>
    {
        private Stack<BSTNode<E>> stack;

        public Iterator(BSTNode<E> node)
        {
            this.stack = new Stack<>();
            while (node != null)
            {
                stack.push(node);
                node = node.left;
            }
        }
        public boolean hasNext()
        {
            return !stack.isEmpty();
        }
        public E next()
        {
            BSTNode<E> goodDays = stack.pop();
            E result = goodDays.data;
            if (goodDays.right != null)
            {
                goodDays = goodDays.right;
                while (goodDays != null)
                {
                    stack.push(goodDays);
                    goodDays = goodDays.left;
                }
            }
            return result;
        }
    }
private static class BSTNode<E>
{
    public E data;
    public BSTNode<E> left;
    public BSTNode<E> right;

    public BSTNode(E data)
    {
        this(data, null, null);
    }
    public BSTNode(E data, BSTNode<E> left, BSTNode<E> right)
    {
        this.data = data;
        this.left = left;
        this.right = right;
    }
}
}

Voici le reste du code pour les références, mais je suis plus concentré sur les méthodes toArray que sur tout. Je ne peux pas comprendre comment les trier dans un tableau. Veuillez aider.

 public E[] toArray()
    {
        List<E> lista = new ArrayList<E>();
        toArray(root, lista);
        E[] good = (E[]) lista.toArray();
        return good;
    }
    private void toArray(BSTNode<E> node, List<E> aList)
    {
        if(node.left != null)
        {
            aList.add(node.left.data);
        }
    }


8 commentaires

Votre exercice se concentre sur la récursivité et demande une réponse récursive. Essayez d'abord de remplir la méthode pour un arbre contenant seulement 1 élément. Puis développez et appelez la méthode "helper" si la gauche ou la droite existe


Je vous suggère de commencer avec un crayon et du papier et de comprendre comment le faire d'abord, puis d'essayer de le coder.


@Ferrybig D'accord, je comprends cela mais je ne sais pas comment l'écrire pour que cela fonctionne. Je peux comprendre l'algorithme, je ne sais tout simplement pas ce qu'il y aurait exactement pour qu'il soit comparé.


Écrivez l'algorithme, testez-le sur papier, avec quelques exemples, puis transformez chaque étape de votre algorithme en fonction.


Je ne sais pas comment le taper. Comme je n'ai pas la moindre idée de la façon d'ajouter les valeurs dans le tableau. Il ne s'agit pas de l'algorithme.


Je n'avais pas réalisé que vous travailliez déjà avec un arbre trié, j'ai noté les étapes pour le parcourir. Cela devrait être assez simple à mettre en œuvre, mais juste au cas où je posterais toute l'exécution, j'espère que cela ajoute de la clarté.


@OscarRyz Merci!


@OscarRyz Je l'ai compris, je l'ai posté ci-dessous.


3 Réponses :


3
votes

Attendez, ceci est un arbre de recherche binaire donc il est déjà trié.

Ensuite, vous devez parcourir l'arbre.

Étant donné que vous avez quelque chose comme:

//B.3
tree = 
    6
   /  \
  5    9

array =[2,3,4]

// B.1
tree = 
    5

array =[2,3,4]

// A
tree = 


array =[2,3,4]

// B.2
tree = 
    5

array =[2,3,4,5]

// B.2
tree = 
    6
   /  \
  5    9

array =[2,3,4,5,6]

// B.3
tree = 
    9

array =[2,3,4,5,6]

// A
tree = 


array =[2,3,4,5,6]

// B.2
tree = 
    9

array =[2,3,4,5,6,9]

Pour l'insérer, vous devez:

Étant donné une racine d'arbre

  • A. Si l'arborescence est nulle, il n'y a rien à insérer.
  • B. Si n'est pas nul:
    • B.1 Tout insérer à gauche
    • B.2 Insérer la racine de l'arbre
    • B.3 Tout insérer à droite

Ce qui ressemblerait à ceci:

// B.2 on the initial tree
tree = 
   4
 /   \
2      6
 \    /  \
  3  5    9

array =[2,3,4]

Donc en appliquant ces étapes sur le tableau:

L'arbre est-il nul? Non, puis exécutez l'étape #B (insérez tout à gauche, racine et tout à droite)

 //A
tree =      

array =[2,3]

Nous prenons la branche gauche et répétons le processus (étape # B.1, insérez tout la gauche):

L'arbre est-il nul? Non, puis exécutez #B

//B.2
tree =      
  3     

array =[2,3]

Puisque la branche de gauche est nulle, la prochaine exécution ressemblerait à ceci:

L'arbre est-il nul? oui, puis retournez

//A
tree =      

array =[2]

Ceci conclura l'étape B.1, nous pouvons maintenant passer à l'étape B.2, insérer la racine

//B.3
tree =      
  3     

array =[2]


0 commentaires

1
votes

Je l'ai compris. Je vais divulguer le code et expliquer ce qui se passe.

En public, je fais une liste qui sera bientôt une liste de tableaux. Ensuite, j'appelle la méthode d'assistance toArray (privée) pour définir les valeurs. Racine pour le premier et lista pour la liste dans laquelle il va entrer. Après avoir créé le tableau et défini la taille avec numElements. Le comparable est là-dedans puisque tout en haut de mon code, c'est ce qu'il étend. Ensuite, placez le tableau that dans la liste. Enfin, retournez-le.

 private void toArray(BSTNode<E> node, List<E> aList)
    {
        if(node != null)
        {
            toArray(node.left, aList);
            aList.add(node.data);
            toArray(node.right, aList);
        }
    }

Dans le privé, je fais de la récursivité. Tant que le nœud n'est pas vide (nul), le tableau recherchera continuellement les nœuds de gauche jusqu'à ce qu'il n'en ait plus (à gauche), ajoutez donc cela dans le tableau. Puis ajoute les bons.

 public E[] toArray()
    {
        List<E> lista = new ArrayList<E>();
        toArray(root, lista);
        E[] arr = (E[]) new Comparable[numElements];
        lista.toArray(arr);
        return arr;
    }

Désolé si c'était difficile à comprendre, je ne suis pas le meilleur pour expliquer les choses, mais cela a fonctionné pour moi.


2 commentaires

Parfait, cela fonctionne parce que votre BST a un itérateur, non?


Bien! J'ai inclus un programme d'exemple de ma réponse initiale. C'était amusant à coder :)



1
votes

Exemple pratique des étapes décrites ici

import java.util.*;
import java.lang.reflect.Array;
import static java.lang.System.out;

class Tree<E extends Comparable<E>> {

    E root;
    Tree<E> left;
    Tree<E> right;

    void insert(E element) {
        if (this.root == null) {
            this.root = element;
            this.left = new Tree<E>();
            this.right = new Tree<E>();
        } else if (element.compareTo(this.root) < 0 ) {
            left.insert(element);
        } else {
            right.insert(element);
        }
    }

    E[] toArray() {
      List<E> a = new ArrayList<>();
      toArray(this, a);
      @SuppressWarnings("unchecked")
      final E[] r = a.toArray((E[]) Array.newInstance(a.get(0).getClass(), a.size()));
      return r;
    }

    // instance method just to retain the generic type E
    private void toArray(Tree<E> t, List<E> list) {
        if (t == null || t.root == null) {
            return;
        } else {
            toArray(t.left, list);
            list.add(t.root);
            toArray(t.right, list);
        }
    }

    public static void main(String ... args) {
        Tree<String> t = new Tree<>();
        t.insert("hola");
        t.insert("adios");
        t.insert("fuimonos");

        System.out.println(Arrays.toString(t.toArray()));
    }
}


0 commentaires