web-dev-qa-db-fra.com

Java structure de données arborescente?

Existe-t-il une bonne structure de données disponible (Java standard) pour représenter un arbre en Java?

Plus précisément, je dois représenter les éléments suivants:

  • L'arbre sur n'importe quel noeud peut avoir un nombre arbitraire d'enfants
  • Chaque nœud (après la racine) est juste une chaîne (dont les enfants sont aussi des chaînes)
  • Je dois pouvoir obtenir tous les enfants (une sorte de liste ou de tableau de chaînes) avec une chaîne d'entrée représentant un nœud donné

Existe-t-il une structure disponible pour cela ou dois-je créer la mienne (dans ce cas, des suggestions de mise en œuvre seraient formidables).

479
ikl

Ici:

public class Tree<T> {
    private Node<T> root;

    public Tree(T rootData) {
        root = new Node<T>();
        root.data = rootData;
        root.children = new ArrayList<Node<T>>();
    }

    public static class Node<T> {
        private T data;
        private Node<T> parent;
        private List<Node<T>> children;
    }
}

C'est une arborescence de base qui peut être utilisée pour String ou tout autre objet. Il est assez facile de mettre en œuvre des arbres simples pour faire ce dont vous avez besoin.

Tout ce que vous devez ajouter sont des méthodes d’ajout, de suppression, de traversée et de constructeurs. La Node est la pierre angulaire de la Tree.

292
jjnguy

Encore une autre arborescence:

public class TreeNode<T> implements Iterable<TreeNode<T>> {

    T data;
    TreeNode<T> parent;
    List<TreeNode<T>> children;

    public TreeNode(T data) {
        this.data = data;
        this.children = new LinkedList<TreeNode<T>>();
    }

    public TreeNode<T> addChild(T child) {
        TreeNode<T> childNode = new TreeNode<T>(child);
        childNode.parent = this;
        this.children.add(childNode);
        return childNode;
    }

    // other features ...

}

Exemple d'utilisation:

TreeNode<String> root = new TreeNode<String>("root");
{
    TreeNode<String> node0 = root.addChild("node0");
    TreeNode<String> node1 = root.addChild("node1");
    TreeNode<String> node2 = root.addChild("node2");
    {
        TreeNode<String> node20 = node2.addChild(null);
        TreeNode<String> node21 = node2.addChild("node21");
        {
            TreeNode<String> node210 = node20.addChild("node210");
        }
    }
}

BONUS
Voir arbre à part entière avec:

  • itérateur
  • recherche
  • Java/C #

https://github.com/gt4dev/yet-another-tree-structure

115
Grzegorz Dev

Il existe en fait une très bonne structure arborescente dans le JDK.

Regardez javax.swing.tree , TreeModel , et TreeNode . Ils sont conçus pour être utilisés avec la JTreePanel mais ils constituent en fait une très bonne implémentation d’arborescence et rien ne vous empêche de l’utiliser sans interface pivotante.

Notez qu'à partir de Java 9, vous souhaiterez peut-être ne pas utiliser ces classes car elles ne figureront pas dans le 'Profils compacts' .

97
Gareth Davis

Et ça?

import Java.util.ArrayList;
import Java.util.Collection;
import Java.util.HashMap;

/**
  * @author [email protected] (Yohann Coppel)
  * 
  * @param <T>
  *          Object's type in the tree.
*/
public class Tree<T> {

  private T head;

  private ArrayList<Tree<T>> leafs = new ArrayList<Tree<T>>();

  private Tree<T> parent = null;

  private HashMap<T, Tree<T>> locate = new HashMap<T, Tree<T>>();

  public Tree(T head) {
    this.head = head;
    locate.put(head, this);
  }

  public void addLeaf(T root, T leaf) {
    if (locate.containsKey(root)) {
      locate.get(root).addLeaf(leaf);
    } else {
      addLeaf(root).addLeaf(leaf);
    }
  }

  public Tree<T> addLeaf(T leaf) {
    Tree<T> t = new Tree<T>(leaf);
    leafs.add(t);
    t.parent = this;
    t.locate = this.locate;
    locate.put(leaf, t);
    return t;
  }

  public Tree<T> setAsParent(T parentRoot) {
    Tree<T> t = new Tree<T>(parentRoot);
    t.leafs.add(this);
    this.parent = t;
    t.locate = this.locate;
    t.locate.put(head, this);
    t.locate.put(parentRoot, t);
    return t;
  }

  public T getHead() {
    return head;
  }

  public Tree<T> getTree(T element) {
    return locate.get(element);
  }

  public Tree<T> getParent() {
    return parent;
  }

  public Collection<T> getSuccessors(T root) {
    Collection<T> successors = new ArrayList<T>();
    Tree<T> tree = getTree(root);
    if (null != tree) {
      for (Tree<T> leaf : tree.leafs) {
        successors.add(leaf.head);
      }
    }
    return successors;
  }

  public Collection<Tree<T>> getSubTrees() {
    return leafs;
  }

  public static <T> Collection<T> getSuccessors(T of, Collection<Tree<T>> in) {
    for (Tree<T> tree : in) {
      if (tree.locate.containsKey(of)) {
        return tree.getSuccessors(of);
      }
    }
    return new ArrayList<T>();
  }

  @Override
  public String toString() {
    return printTree(0);
  }

  private static final int indent = 2;

  private String printTree(int increment) {
    String s = "";
    String inc = "";
    for (int i = 0; i < increment; ++i) {
      inc = inc + " ";
    }
    s = inc + head;
    for (Tree<T> child : leafs) {
      s += "\n" + child.printTree(increment + indent);
    }
    return s;
  }
}
44
MountainX

I écrit une petite bibliothèque qui gère les arbres génériques. C'est beaucoup plus léger que le swing. J'ai aussi un projet maven pour cela.

23
Vivin Paliath
public class Tree {
    private List<Tree> leaves = new LinkedList<Tree>();
    private Tree parent = null;
    private String data;

    public Tree(String data, Tree parent) {
        this.data = data;
        this.parent = parent;
    }
}

Évidemment, vous pouvez ajouter des méthodes utilitaires pour ajouter/supprimer des enfants.

17
PaulJWilliams

Vous devriez commencer par définir ce qu'est un arbre (pour le domaine). Pour ce faire, définissez d'abord interface. Toutes les arborescences ne sont pas modifiables, étant capable d'ajouter et de supprimer des nœuds devrait être une fonctionnalité optionnelle, donc nous faisons une interface supplémentaire pour cela.

Il n'est pas nécessaire de créer des objets nœud contenant les valeurs, je considère en fait cela comme un défaut de conception majeur et une surcharge dans la plupart des implémentations d'arborescence. Si vous regardez Swing, la TreeModel ne contient pas de classes de nœuds (seul DefaultTreeModel utilise TreeNode), car elles ne sont pas vraiment nécessaires.

public interface Tree <N extends Serializable> extends Serializable {
    List<N> getRoots ();
    N getParent (N node);
    List<N> getChildren (N node);
}

Structure d'arborescence modifiable (permet d'ajouter et de supprimer des nœuds):

public interface MutableTree <N extends Serializable> extends Tree<N> {
    boolean add (N parent, N node);
    boolean remove (N node, boolean cascade);
}

Étant donné ces interfaces, le code qui utilise des arbres n'a pas à se préoccuper beaucoup de la façon dont l'arbre est implémenté. Cela vous permet d'utiliser des implémentations génériques ainsi que spécialisées , où vous réalisez l’arbre en déléguant des fonctions à une autre API.

Exemple: arborescence de fichiers

public class FileTree implements Tree<File> {

    @Override
    public List<File> getRoots() {
        return Arrays.stream(File.listRoots()).collect(Collectors.toList());
    }

    @Override
    public File getParent(File node) {
        return node.getParentFile();
    }

    @Override
    public List<File> getChildren(File node) {
        if (node.isDirectory()) {
            File[] children = node.listFiles();
            if (children != null) {
                return Arrays.stream(children).collect(Collectors.toList());
            }
        }
        return Collections.emptyList();
    }
}

Exemple: arborescence générique (basé sur les relations parent/enfant):

public class MappedTreeStructure<N extends Serializable> implements MutableTree<N> {

    public static void main(String[] args) {

        MutableTree<String> tree = new MappedTreeStructure<>();
        tree.add("A", "B");
        tree.add("A", "C");
        tree.add("C", "D");
        tree.add("E", "A");
        System.out.println(tree);
    }

    private final Map<N, N> nodeParent = new HashMap<>();
    private final LinkedHashSet<N> nodeList = new LinkedHashSet<>();

    private void checkNotNull(N node, String parameterName) {
        if (node == null)
            throw new IllegalArgumentException(parameterName + " must not be null");
    }

    @Override
    public boolean add(N parent, N node) {
        checkNotNull(parent, "parent");
        checkNotNull(node, "node");

        // check for cycles
        N current = parent;
        do {
            if (node.equals(current)) {
                throw new IllegalArgumentException(" node must not be the same or an ancestor of the parent");
            }
        } while ((current = getParent(current)) != null);

        boolean added = nodeList.add(node);
        nodeList.add(parent);
        nodeParent.put(node, parent);
        return added;
    }

    @Override
    public boolean remove(N node, boolean cascade) {
        checkNotNull(node, "node");

        if (!nodeList.contains(node)) {
            return false;
        }
        if (cascade) {
            for (N child : getChildren(node)) {
                remove(child, true);
            }
        } else {
            for (N child : getChildren(node)) {
                nodeParent.remove(child);
            }
        }
        nodeList.remove(node);
        return true;
    }

    @Override
    public List<N> getRoots() {
        return getChildren(null);
    }

    @Override
    public N getParent(N node) {
        checkNotNull(node, "node");
        return nodeParent.get(node);
    }

    @Override
    public List<N> getChildren(N node) {
        List<N> children = new LinkedList<>();
        for (N n : nodeList) {
            N parent = nodeParent.get(n);
            if (node == null && parent == null) {
                children.add(n);
            } else if (node != null && parent != null && parent.equals(node)) {
                children.add(n);
            }
        }
        return children;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        dumpNodeStructure(builder, null, "- ");
        return builder.toString();
    }

    private void dumpNodeStructure(StringBuilder builder, N node, String prefix) {
        if (node != null) {
            builder.append(prefix);
            builder.append(node.toString());
            builder.append('\n');
            prefix = "  " + prefix;
        }
        for (N child : getChildren(node)) {
            dumpNodeStructure(builder, child, prefix);
        }
    }
}
16
Peter Walser

Aucune réponse ne mentionne un code trop simpliste mais fonctionnel, donc voici:

public class TreeNodeArray<T> {
    public T value;
    public final  Java.util.List<TreeNodeArray<T>> kids =  new Java.util.ArrayList<TreeNodeArray<T>>();
}
10
peenut

Vous pouvez utiliser n'importe quelle API XML de Java en tant que Document et Node..as, XML est une structure arborescente avec des chaînes.

10

Si vous codez un tableau blanc, passez une entrevue ou envisagez tout simplement d’utiliser un arbre, leur verbosité est un peu exagérée.

Il faut en plus dire que la raison pour laquelle un arbre ne se trouve pas là, comme par exemple une Pair (à propos de laquelle on pourrait dire la même chose), est parce que vous devriez encapsuler vos données dans la classe qui les utilise, - and la mise en oeuvre la plus simple ressemble à ceci:

/***
/* Within the class that's using a binary tree for any reason. You could 
/* generalize with generics IFF the parent class needs different value types.
 */
private class Node {
  public String value;
  public Node[] nodes; // Or an Iterable<Node> nodes;
}

C'est vraiment ça pour un arbre de largeur arbitraire.

Si vous voulez un arbre binaire, il est souvent plus facile de l'utiliser avec des champs nommés:

private class Node { // Using package visibility is an option
  String value;
  Node left;
  Node right;
}

Ou si vous vouliez un essai:

private class Node {
  String value;
  Map<char, Node> nodes;
}

Maintenant tu as dit que tu voulais

pour pouvoir obtenir tous les enfants (une sorte de liste ou de tableau de chaînes) à partir d'une chaîne d'entrée représentant un nœud donné

Cela ressemble à vos devoirs.
Mais puisque je suis à peu près sûr que toute échéance est maintenant passée…

import Java.util.Arrays;
import Java.util.ArrayList;
import Java.util.List;

public class kidsOfMatchTheseDays {
 static private class Node {
   String value;
   Node[] nodes;
 }

 // Pre-order; you didn't specify.
 static public List<String> list(Node node, String find) {
   return list(node, find, new ArrayList<String>(), false);
 }

 static private ArrayList<String> list(
     Node node,
     String find,
     ArrayList<String> list,
     boolean add) {
   if (node == null) {
     return list;
   }
   if (node.value.equals(find)) {
     add = true;
   }
   if (add) {
     list.add(node.value);
   }
   if (node.nodes != null) {
     for (Node child: node.nodes) {
       list(child, find, list, add);
     }
   }
   return list;
 }

 public static final void main(String... args) {
   // Usually never have to do setup like this, so excuse the style
   // And it could be cleaner by adding a constructor like:
   //     Node(String val, Node... children) {
   //         value = val;
   //         nodes = children;
   //     }
   Node tree = new Node();
   tree.value = "root";
   Node[] n = {new Node(), new Node()};
   tree.nodes = n;
   tree.nodes[0].value = "leftish";
   tree.nodes[1].value = "rightish-leafy";
   Node[] nn = {new Node()};
   tree.nodes[0].nodes = nn;
   tree.nodes[0].nodes[0].value = "off-leftish-leaf";
   // Enough setup
   System.out.println(Arrays.toString(list(tree, args[0]).toArray()));
 }
}

Cela vous amène à utiliser comme:

$ Java kidsOfMatchTheseDays leftish
[leftish, off-leftish-leaf]
$ Java kidsOfMatchTheseDays root
[root, leftish, off-leftish-leaf, rightish-leafy]
$ Java kidsOfMatchTheseDays rightish-leafy
[rightish-leafy]
$ Java kidsOfMatchTheseDays a
[]
7
dlamblin

Il existe quelques structures de données arborescentes en Java, telles que DefaultMutableTreeNode dans JDK Swing, le package Tree dans un analyseur syntaxique Stanford et d'autres codes de jouets. Mais aucun d’entre eux n’est suffisant et pourtant suffisamment petit pour un usage général.

Java-tree le projet tente de fournir une autre structure de données d'arborescence à usage général en Java. La différence entre ceci et les autres sont

  • Complètement gratuit. Vous pouvez l'utiliser n'importe où (sauf dans vos devoirs: P)
  • Petit mais assez général. Je mets tout ce qui concerne la structure de données dans un seul fichier de classe, il serait donc facile de copier/coller.
  • Pas seulement un jouet. Je connais des dizaines de codes d'arborescence Java qui ne peuvent gérer que des arbres binaires ou des opérations limitées. Cet TreeNode est beaucoup plus que cela. Il fournit différentes façons de visiter les nœuds, tels que pré-commande, post-commande, largeur, tout d'abord, feuilles, chemin d'accès à la racine, etc. De plus, des itérateurs sont également fournis pour la suffisance.
  • Plus d'utils seront ajoutés. Je suis prêt à ajouter d'autres opérations pour rendre ce projet complet, en particulier si vous envoyez une demande via github.
7
Yifan Peng

Dans le même ordre d'idées que la réponse de Gareth, vérifiez DefaultMutableTreeNode . Ce n'est pas générique, mais autrement semble correspondre à la facture. Même si cela se trouve dans le package javax.swing, cela ne dépend pas des classes AWT ou Swing. En fait, le code source a en fait le commentaire // ISSUE: this class depends on nothing in AWT -- move to Java.util?

7
Mark
public abstract class Node {
  List<Node> children;

  public List<Node> getChidren() {
    if (children == null) {
      children = new ArrayList<>();
    }
    return chidren;
  }
}

Aussi simple que possible et très facile à utiliser. Pour l'utiliser, étendez-le:

public class MenuItem extends Node {
  String label;
  String href;
  ...
}
5
bretter

Puisque la question demande une structure de données disponible, un arbre peut être construit à partir de listes ou de tableaux:

Object[] tree = new Object[2];
tree[0] = "Hello";
{
  Object[] subtree = new Object[2];
  subtree[0] = "Goodbye";
  subtree[1] = "";
  tree[1] = subtree;
}

instanceof peut être utilisé pour déterminer si un élément est un sous-arbre ou un nœud de terminal.

5
Olathe

J'ai écrit une petite classe "TreeMap" basée sur "HashMap" qui prend en charge l'ajout de chemins:

import Java.util.HashMap;
import Java.util.LinkedList;

public class TreeMap<T> extends LinkedHashMap<T, TreeMap<T>> {

    public void put(T[] path) {
        LinkedList<T> list = new LinkedList<>();
        for (T key : path) {
            list.add(key);
        }
        return put(list);
    }

    public void put(LinkedList<T> path) {
        if (path.isEmpty()) {
            return;
        }
        T key = path.removeFirst();
        TreeMap<T> val = get(key);
        if (val == null) {
            val = new TreeMap<>();
            put(key, val);
        }
        val.put(path);
    }

}

Il peut être utilisé pour stocker un arbre d'objets de type "T" (générique), mais ne prend pas (encore) en charge le stockage de données supplémentaires dans ses nœuds. Si vous avez un fichier comme celui-ci:

root, child 1
root, child 1, child 1a
root, child 1, child 1b
root, child 2
root, child 3, child 3a

Ensuite, vous pouvez en faire un arbre en exécutant:

TreeMap<String> root = new TreeMap<>();
Scanner scanner = new Scanner(new File("input.txt"));
while (scanner.hasNextLine()) {
  root.put(scanner.nextLine().split(", "));
}

Et vous obtiendrez un bel arbre. Il devrait être facile de s'adapter à vos besoins.

3
mevdschee

Dans le passé, je viens d'utiliser une carte imbriquée pour cela. C’est ce que j’utilise aujourd’hui, c’est très simple mais cela répond à mes besoins. Peut-être que cela aidera un autre.

import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.ObjectMapper;

import Java.util.HashMap;
import Java.util.Map;
import Java.util.TreeMap;

/**
 * Created by kic on 16.07.15.
 */
public class NestedMap<K, V> {
    private final Map root = new HashMap<>();

    public NestedMap<K, V> put(K key) {
        Object nested = root.get(key);

        if (nested == null || !(nested instanceof NestedMap)) root.put(key, nested = new NestedMap<>());
        return (NestedMap<K, V>) nested;
    }

    public Map.Entry<K,V > put(K key, V value) {
        root.put(key, value);

        return (Map.Entry<K, V>) root.entrySet().stream().filter(e -> ((Map.Entry) e).getKey().equals(key)).findFirst().get();
    }

    public NestedMap<K, V> get(K key) {
        return (NestedMap<K, V>) root.get(key);
    }

    public V getValue(K key) {
        return (V) root.get(key);
    }

    @JsonValue
    public Map getRoot() {
        return root;
    }

    public static void main(String[] args) throws Exception {
        NestedMap<String, Integer> test = new NestedMap<>();
        test.put("a").put("b").put("c", 12);
        Map.Entry<String, Integer> foo = test.put("a").put("b").put("d", 12);
        test.put("b", 14);
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(test));

        foo.setValue(99);
        System.out.println(mapper.writeValueAsString(test));

        System.out.println(test.get("a").get("b").getValue("d"));
    }
}
3
KIC

Par exemple :

import Java.util.ArrayList;
import Java.util.List;



/**
 * 
 * @author X2
 *
 * @param <T>
 */
public class HisTree<T> 
{
    private Node<T> root;

    public HisTree(T rootData) 
    {
        root = new Node<T>();
        root.setData(rootData);
        root.setChildren(new ArrayList<Node<T>>());
    }

}

class Node<T> 
{

    private T data;
    private Node<T> parent;
    private List<Node<T>> children;

    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
    public Node<T> getParent() {
        return parent;
    }
    public void setParent(Node<T> parent) {
        this.parent = parent;
    }
    public List<Node<T>> getChildren() {
        return children;
    }
    public void setChildren(List<Node<T>> children) {
        this.children = children;
    }
}
3
JAN
    // TestTree.Java
// A simple test to see how we can build a tree and populate it
//
import Java.awt.*;
import Java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;

public class TestTree extends JFrame {

  JTree tree;
  DefaultTreeModel treeModel;

  public TestTree( ) {
    super("Tree Test Example");
    setSize(400, 300);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
  }

  public void init( ) {
    // Build up a bunch of TreeNodes. We use DefaultMutableTreeNode because the
    // DefaultTreeModel can use it to build a complete tree.
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
    DefaultMutableTreeNode subroot = new DefaultMutableTreeNode("SubRoot");
    DefaultMutableTreeNode leaf1 = new DefaultMutableTreeNode("Leaf 1");
    DefaultMutableTreeNode leaf2 = new DefaultMutableTreeNode("Leaf 2");

    // Build our tree model starting at the root node, and then make a JTree out
    // of it.
    treeModel = new DefaultTreeModel(root);
    tree = new JTree(treeModel);

    // Build the tree up from the nodes we created.
    treeModel.insertNodeInto(subroot, root, 0);
    // Or, more succinctly:
    subroot.add(leaf1);
    root.add(leaf2);

    // Display it.
    getContentPane( ).add(tree, BorderLayout.CENTER);
  }

  public static void main(String args[]) {
    TestTree tt = new TestTree( );
    tt.init( );
    tt.setVisible(true);
  }
}
2
Tony Narloch

Vous pouvez utiliser la classe HashTree incluse dans Apache JMeter qui fait partie du projet Jakarta.

La classe HashTree est incluse dans le package org.Apache.jorphan.collections. Bien que ce package ne soit pas publié en dehors du projet JMeter, vous pouvez l'obtenir facilement:

1) Téléchargez le sources JMeter .

2) Créez un nouveau package.

3) Copiez dessus/src/jorphan/org/Apache/jorphan/collections /. Tous les fichiers sauf Data.Java

4) Copiez également /src/jorphan/org/Apache/jorphan/util/JOrphanUtils.Java

5) HashTree est prêt à être utilisé.

2
David

Il n'y a pas de structure de données spécifique dans Java qui convienne à vos besoins. Vos exigences sont assez spécifiques et pour cela vous devez concevoir votre propre structure de données. En examinant vos besoins, n'importe qui peut affirmer que vous avez besoin d'une sorte d'arbre n-aire doté de fonctionnalités spécifiques. Vous pouvez concevoir votre structure de données de la manière suivante:

  1. La structure du nœud de l’arborescence ressemblerait au contenu du nœud et à une liste d’enfants du type: class Node {{String value; Liste des enfants;}
  2. Vous devez récupérer les enfants d'une chaîne donnée pour que vous puissiez avoir 2 méthodes: 1: Node searchNode (String str), renverra le nœud ayant la même valeur que l'entrée donnée (utilisez BFS pour la recherche) 2: List getChildren (String str): cette méthode appelle en interne le searchNode pour obtenir le nœud ayant la même chaîne, puis crée la liste de toutes les valeurs de chaîne des enfants et le renvoie.
  3. Vous devrez également insérer une chaîne dans l’arbre. Vous devrez écrire une méthode say void insert (Chaîne parent, Valeur de chaîne): ceci cherchera à nouveau le nœud ayant une valeur égale à parent et vous pourrez ensuite créer un Node avec une valeur donnée et l'ajouter à la liste. des enfants au parent trouvé.

Je suggérerais que vous écriviez la structure du nœud dans une classe telle que Class Node _ {String value; Répertoriez les enfants;} et toutes les autres méthodes telles que search, insert et getChildren dans une autre classe NodeUtils, de sorte que vous puissiez également transmettre la racine de l'arborescence pour effectuer des opérations sur une arborescence spécifique, comme par exemple: class NodeUtils {public static Node search ( Node root, String value) {// exécute BFS et renvoie Node}

2
aman rastogi

J'ai écrit une bibliothèque d'arbres qui fonctionne bien avec Java8 et qui n'a pas d'autres dépendances. Il fournit également une interprétation approximative de certaines idées issues de la programmation fonctionnelle et vous permet de mapper/filtrer/élaguer/rechercher l’arbre ou les sous-arbres entiers.

https://github.com/RutledgePaulV/Prune

L'implémentation ne fait rien de spécial avec l'indexation et je ne me suis pas éloigné de la récursion. Il est donc possible qu'avec des arbres de grande taille, les performances se dégradent et que vous puissiez détruire la pile. Mais si tout ce dont vous avez besoin est un arbre simple de profondeur faible à modérée, je pense que cela fonctionne assez bien. Il fournit une définition d'égalité saine (basée sur la valeur) et une implémentation toString qui vous permet de visualiser l'arbre!

2
RutledgePaulV

Veuillez vérifier le code ci-dessous, où j'ai utilisé des structures de données Tree, sans utiliser les classes Collection. Le code peut contenir des bugs/améliorations, mais veuillez l’utiliser juste pour référence.

package com.datastructure.tree;

public class BinaryTreeWithoutRecursion <T> {

    private TreeNode<T> root;


    public BinaryTreeWithoutRecursion (){
        root = null;
    }


    public void insert(T data){
        root =insert(root, data);

    }

    public TreeNode<T>  insert(TreeNode<T> node, T data ){

        TreeNode<T> newNode = new TreeNode<>();
        newNode.data = data;
        newNode.right = newNode.left = null;

        if(node==null){
            node = newNode;
            return node;
        }
        Queue<TreeNode<T>> queue = new Queue<TreeNode<T>>();
        queue.enque(node);
        while(!queue.isEmpty()){

            TreeNode<T> temp= queue.deque();
            if(temp.left!=null){
                queue.enque(temp.left);
            }else
            {
                temp.left = newNode;

                queue =null;
                return node;
            }
            if(temp.right!=null){
                queue.enque(temp.right);
            }else
            {
                temp.right = newNode;
                queue =null;
                return node;
            }
        }
        queue=null;
        return node; 


    }

    public void inOrderPrint(TreeNode<T> root){
        if(root!=null){

            inOrderPrint(root.left);
            System.out.println(root.data);
            inOrderPrint(root.right);
        }

    }

    public void postOrderPrint(TreeNode<T> root){
        if(root!=null){

            postOrderPrint(root.left);

            postOrderPrint(root.right);
            System.out.println(root.data);
        }

    }

    public void preOrderPrint(){
        preOrderPrint(root);
    }


    public void inOrderPrint(){
        inOrderPrint(root);
    }

    public void postOrderPrint(){
        inOrderPrint(root);
    }


    public void preOrderPrint(TreeNode<T> root){
        if(root!=null){
            System.out.println(root.data);
            preOrderPrint(root.left);
            preOrderPrint(root.right);
        }

    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        BinaryTreeWithoutRecursion <Integer> ls=  new BinaryTreeWithoutRecursion <>();
        ls.insert(1);
        ls.insert(2);
        ls.insert(3);
        ls.insert(4);
        ls.insert(5);
        ls.insert(6);
        ls.insert(7);
        //ls.preOrderPrint();
        ls.inOrderPrint();
        //ls.postOrderPrint();

    }

}
1
Amit Mathur

Vous pouvez utiliser la classe TreeSet dans Java.util. *. Il fonctionne comme un arbre de recherche binaire, il est donc déjà trié. La classe TreeSet implémente les interfaces Iterable, Collection et Set. Vous pouvez traverser l'arbre avec l'itérateur comme un ensemble.

TreeSet<String> treeSet = new TreeSet<String>();
Iterator<String> it  = treeSet.Iterator();
while(it.hasNext()){
...
}

Vous pouvez vérifier Java Doc et quelques autres .

1
Oguz