Structure de données d’arborescence Java?

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

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

  • L’arbre à n’importe quel nœud 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 être capable d’obtenir tous les enfants (une sorte de liste ou un 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 le mien (si oui, les suggestions de mise en œuvre seraient géniales).

Ici:

public class Tree { private Node root; public Tree(T rootData) { root = new Node(); root.data = rootData; root.children = new ArrayList>(); } public static class Node { private T data; private Node parent; private List> children; } } 

C’est une arborescence de base qui peut être utilisée pour Ssortingng ou tout autre object. Il est assez facile d’implémenter des arbres simples pour faire ce dont vous avez besoin.

Tout ce que vous avez besoin d’append, ce sont des méthodes pour append, supprimer, traverser et construire. Le Node est le composant de base de l’ Tree .

Encore une autre structure d’arbre:

 public class TreeNode implements Iterable> { T data; TreeNode parent; List> children; public TreeNode(T data) { this.data = data; this.children = new LinkedList>(); } public TreeNode addChild(T child) { TreeNode childNode = new TreeNode(child); childNode.parent = this; this.children.add(childNode); return childNode; } // other features ... } 

Exemple d’utilisation:

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

PRIME
Voir arbre à part entière avec:

  • iterator
  • recherche
  • Java / C #

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

Il existe en fait une très bonne structure d’arbre implémentée dans le JDK.

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

Notez qu’à partir de Java 9, vous souhaiterez peut-être ne pas utiliser ces classes car elles ne seront pas présentes dans les «profils compacts» .

Et ça?

 import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; /** * @author ycoppel@google.com (Yohann Coppel) * * @param  * Object's type in the tree. */ public class Tree { private T head; private ArrayList> leafs = new ArrayList>(); private Tree parent = null; private HashMap> locate = new HashMap>(); 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 addLeaf(T leaf) { Tree t = new Tree(leaf); leafs.add(t); t.parent = this; t.locate = this.locate; locate.put(leaf, t); return t; } public Tree setAsParent(T parentRoot) { Tree t = new Tree(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 getTree(T element) { return locate.get(element); } public Tree getParent() { return parent; } public Collection getSuccessors(T root) { Collection successors = new ArrayList(); Tree tree = getTree(root); if (null != tree) { for (Tree leaf : tree.leafs) { successors.add(leaf.head); } } return successors; } public Collection> getSubTrees() { return leafs; } public static  Collection getSuccessors(T of, Collection> in) { for (Tree tree : in) { if (tree.locate.containsKey(of)) { return tree.getSuccessors(of); } } return new ArrayList(); } @Override public Ssortingng toSsortingng() { return printTree(0); } private static final int indent = 2; private Ssortingng printTree(int increment) { Ssortingng s = ""; Ssortingng inc = ""; for (int i = 0; i < increment; ++i) { inc = inc + " "; } s = inc + head; for (Tree child : leafs) { s += "\n" + child.printTree(increment + indent); } return s; } } 

J’ai é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.

 public class Tree { private List leaves = new LinkedList(); private Tree parent = null; private Ssortingng data; public Tree(Ssortingng data, Tree parent) { this.data = data; this.parent = parent; } } 

Vous pouvez évidemment append des méthodes utilitaires pour append / supprimer des enfants.

Vous devez commencer par définir ce qu’est un arbre (pour le domaine), en définissant d’abord l’ interface . Toutes les structures d’arborescence ne sont pas modifiables, le fait de pouvoir append et supprimer des nœuds devrait être une fonctionnalité facultative, nous en faisons donc une interface supplémentaire.

Il n’est pas nécessaire de créer des objects de nœud contenant les valeurs . En fait, je considère que c’est un défaut de conception majeur et une surcharge dans la plupart des implémentations d’arborescence. Si vous regardez Swing, le TreeModel est exempt de classes de nœuds (seul DefaultTreeModel utilise DefaultTreeModel ), car ils ne sont pas vraiment nécessaires.

 public interface Tree  extends Serializable { public List getRoots (); public N getParent (N node); public List getChildren (N node); } public interface MutableTree  extends Tree { public boolean add (N parent, N node); public boolean remove (N node, boolean cascade); } 

Compte tenu de ces interfaces, le code qui utilise des arbres ne doit pas trop se soucier de la façon dont l’arborescence est implémentée. Cela vous permet d’utiliser des implémentations génériques ainsi que des implémentations spécialisées , où vous réalisez l’arborescence en déléguant des fonctions à une autre API.
Exemple: arborescence de fichiers.

 public class MappedTreeStructure implements MutableTree { public static void main(Ssortingng[] args) { MutableTree 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 nodeParent = new HashMap(); private final LinkedHashSet nodeList = new LinkedHashSet(); private void checkNotNull(N node, Ssortingng 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 getRoots() { return getChildren(null); } @Override public N getParent(N node) { checkNotNull(node, "node"); return nodeParent.get(node); } @Override public List getChildren(N node) { List 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 Ssortingng toSsortingng() { SsortingngBuilder builder = new SsortingngBuilder(); dumpNodeStructure(builder, null, "- "); return builder.toSsortingng(); } private void dumpNodeStructure(SsortingngBuilder builder, N node, Ssortingng prefix) { if (node != null) { builder.append(prefix); builder.append(node.toSsortingng()); builder.append('\n'); prefix = " " + prefix; } for (N child : getChildren(node)) { dumpNodeStructure(builder, child, prefix); } } } 

Aucune réponse ne mentionne un code trop simplifié mais fonctionnel, alors voici:

 public class TreeNodeArray { public T value; public final java.util.List> kids = new java.util.ArrayList>(); } 

Vous pouvez utiliser n’importe quelle API XML de Java en tant que document et nœud, car XML est une arborescence avec des chaînes.

Il existe deux structures de données arborescentes en Java, telles que DefaultMutableTreeNode dans JDK Swing, le package de l’parsingur Tree in Stanford et d’autres codes de jouet. Mais aucun de ceux-ci ne sont suffisants, mais assez petits pour un usage général.

Le projet Java-tree tente de fournir une autre structure de données arborescente polyvalente 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 de la structure de données dans un fichier de classe, il serait donc facile de copier / coller.
  • Pas seulement des jouets. Je connais des dizaines de codes d’arborescence Java qui ne peuvent gérer que des arbres binarys ou des opérations limitées. Ce TreeNode est beaucoup plus que cela. Il fournit différentes manières de visiter des nœuds, telles que la précommande, le post-ordre, la largeur, les feuilles, le chemin d’access à la racine, etc. De plus, les iterators sont également fournis pour la suffisance.
  • Plus d’utils seront ajoutés. Je suis prêt à append plus d’opérations pour rendre ce projet complet, surtout si vous envoyez une demande via github.

Dans le même sens que la réponse de Gareth, consultez DefaultMutableTreeNode . Ce n’est pas générique, mais semble correspondre à la facture. Même s’il se trouve dans le package javax.swing, il ne dépend d’aucune classe AWT ou Swing. En fait, le code source a effectivement le commentaire // ISSUE: this class depends on nothing in AWT -- move to java.util?

Si vous effectuez un codage sur tableau blanc, une interview ou même simplement pour planifier l’utilisation d’un arbre, la verbosité de ces éléments est un peu trop importante.

Il faut dire en outre que la raison pour laquelle une arborescence ne s’y trouve pas, par exemple, une Pair (dont on pourrait dire la même chose), est que vous devriez encapsuler vos données dans la classe qui les utilise et que l’implémentation la plus simple :

 /*** /* 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 Ssortingng value; public Node[] nodes; // Or an Iterable nodes; } 

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

Si vous vouliez un arbre binary, il est souvent plus simple d’utiliser des champs nommés:

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

Ou si vous vouliez un sortinge:

 private class Node { Ssortingng value; Map nodes; } 

Maintenant tu as dit que tu voulais

pour être capable d’obtenir tous les enfants (une sorte de liste ou un tableau de chaînes) donné une chaîne d’entrée représentant un noeud donné

Cela ressemble à vos devoirs.
Mais comme je suis raisonnablement sûr que tout délai est maintenant passé…

 import java.util.Arrays; import java.util.ArrayList; import java.util.List; public class kidsOfMatchTheseDays { static private class Node { Ssortingng value; Node[] nodes; } // Pre-order; you didn't specify. static public List list(Node node, Ssortingng find) { return list(node, find, new ArrayList(), false); } static private ArrayList list( Node node, Ssortingng find, ArrayList 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(Ssortingng... args) { // Usually never have to do setup like this, so excuse the style // And it could be cleaner by adding a constructor like: // Node(Ssortingng 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.toSsortingng(list(tree, args[0]).toArray())); } } 

Cela vous permet d’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 [] 

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 une sous-arborescence ou un noeud terminal.

 public abstract class Node { List children; public List 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 { Ssortingng label; Ssortingng href; ... } 

Par exemple :

 import java.util.ArrayList; import java.util.List; /** * * @author X2 * * @param  */ public class HisTree { private Node root; public HisTree(T rootData) { root = new Node(); root.setData(rootData); root.setChildren(new ArrayList>()); } } class Node { private T data; private Node parent; private List> children; public T getData() { return data; } public void setData(T data) { this.data = data; } public Node getParent() { return parent; } public void setParent(Node parent) { this.parent = parent; } public List> getChildren() { return children; } public void setChildren(List> children) { this.children = children; } } 

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 sorti en dehors du projet JMeter, vous pouvez l’obtenir facilement:

1) Téléchargez les sources JMeter .

2) Créez un nouveau package.

3) Copiez-le sur / 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 à utiliser.

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 avoir des bogues / améliorations, mais s’il vous plaît utilisez-le juste pour référence

 package com.datastructure.tree; public class BinaryTreeWithoutRecursion  { private TreeNode root; public BinaryTreeWithoutRecursion (){ root = null; } public void insert(T data){ root =insert(root, data); } public TreeNode insert(TreeNode node, T data ){ TreeNode newNode = new TreeNode<>(); newNode.data = data; newNode.right = newNode.left = null; if(node==null){ node = newNode; return node; } Queue> queue = new Queue>(); queue.enque(node); while(!queue.isEmpty()){ TreeNode 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 root){ if(root!=null){ inOrderPrint(root.left); System.out.println(root.data); inOrderPrint(root.right); } } public void postOrderPrint(TreeNode 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 root){ if(root!=null){ System.out.println(root.data); preOrderPrint(root.left); preOrderPrint(root.right); } } /** * @param args */ public static void main(Ssortingng[] args) { // TODO Auto-generated method stub BinaryTreeWithoutRecursion  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(); } } 

Il n’y a pas de structure de données spécifique en Java qui corresponde à vos besoins. Vos exigences sont assez spécifiques et pour cela vous devez concevoir votre propre structure de données. En examinant vos besoins, tout le monde peut dire que vous avez besoin d’une sorte d’arborescence n-aire avec des 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’arbre serait comme le contenu du nœud et la liste des enfants comme: class Node {Ssortingng value; Listez les enfants}
  2. Vous devez récupérer les enfants d’une chaîne donnée, vous pouvez donc avoir 2 méthodes 1: Node searchNode (Ssortingng str), retournera le nœud qui a la même valeur que l’entrée donnée (utilisez BFS pour la recherche) 2: List getChildren (Ssortingng str): cette méthode appellera en interne le searchNode pour que le nœud ait la même chaîne, puis il créera la liste de toutes les valeurs de chaîne des enfants et les renverra.
  3. Vous devrez également insérer une chaîne dans l’arborescence. Vous devrez écrire une méthode, disons void insert (Ssortingng parent, Ssortingng value): cela recherchera à nouveau le nœud ayant une valeur égale à parent et vous pourrez ensuite créer un nœud avec une valeur donnée et l’append à la liste des enfants du parent trouvé. .

Je suggère, vous écrivez la structure du nœud dans une classe comme Class Node {Ssortingng value; Répertorie les enfants;} et toutes les autres méthodes telles que search, insert et getChildren dans une autre classe NodeUtils afin de pouvoir passer la racine de l’arbre pour effectuer des opérations sur une arborescence spécifique: class NodeUtils {recherche statique statique des noeuds {// effectuer BFS et retourner le noeud}

Dans le passé, je viens d’utiliser une carte nestede pour cela. C’est ce que j’utilise aujourd’hui, c’est très simple mais ça répond à mes besoins. Peut-être que cela en 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 { private final Map root = new HashMap<>(); public NestedMap put(K key) { Object nested = root.get(key); if (nested == null || !(nested instanceof NestedMap)) root.put(key, nested = new NestedMap<>()); return (NestedMap) nested; } public Map.Entry put(K key, V value) { root.put(key, value); return (Map.Entry) root.entrySet().stream().filter(e -> ((Map.Entry) e).getKey().equals(key)).findFirst().get(); } public NestedMap get(K key) { return (NestedMap) root.get(key); } public V getValue(K key) { return (V) root.get(key); } @JsonValue public Map getRoot() { return root; } public static void main(Ssortingng[] args) throws Exception { NestedMap test = new NestedMap<>(); test.put("a").put("b").put("c", 12); Map.Entry foo = test.put("a").put("b").put("d", 12); test.put("b", 14); ObjectMapper mapper = new ObjectMapper(); System.out.println(mapper.writeValueAsSsortingng(test)); foo.setValue(99); System.out.println(mapper.writeValueAsSsortingng(test)); System.out.println(test.get("a").get("b").getValue("d")); } } 
  // 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(Ssortingng args[]) { TestTree tt = new TestTree( ); tt.init( ); tt.setVisible(true); } } 

J’ai écrit une bibliothèque d’arbre qui joue bien avec Java8 et qui n’a pas d’autres dépendances. Il fournit également une interprétation libre de certaines idées issues de la functional programming 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 particulier avec l’indexation et je ne me suis pas éloignée de la récursivité, il est donc possible qu’avec des arbres de grande taille, les performances se dégradent et que vous puissiez faire sauter la stack. Mais si tout ce dont vous avez besoin est un arbre simple de petite à moyenne profondeur, je pense que cela fonctionne assez bien. Il fournit une définition saine (basée sur la valeur) de l’égalité et une implémentation toSsortingng qui vous permet de visualiser l’arbre!

Vous pouvez utiliser la classe TreeSet dans java.util. *. Il fonctionne comme un arbre de recherche binary, il est donc déjà sortingé. La classe TreeSet implémente les interfaces Iterable, Collection et Set. Vous pouvez parcourir l’arborescence avec un iterator comme un ensemble.

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

Vous pouvez vérifier, Java Doc et d’ autres .

Implémentation de l’arborescence personnalisée de Tree sans utiliser le framework Collection. Il contient différentes opérations fondamentales nécessaires dans l’implémentation de l’arborescence.

 class Node { int data; Node left; Node right; public Node(int ddata, Node left, Node right) { this.data = ddata; this.left = null; this.right = null; } public void displayNode(Node n) { System.out.print(n.data + " "); } } class BinaryTree { Node root; public BinaryTree() { this.root = null; } public void insertLeft(int parent, int leftvalue ) { Node n = find(root, parent); Node leftchild = new Node(leftvalue, null, null); n.left = leftchild; } public void insertRight(int parent, int rightvalue) { Node n = find(root, parent); Node rightchild = new Node(rightvalue, null, null); n.right = rightchild; } public void insertRoot(int data) { root = new Node(data, null, null); } public Node getRoot() { return root; } public Node find(Node n, int key) { Node result = null; if (n == null) return null; if (n.data == key) return n; if (n.left != null) result = find(n.left, key); if (result == null) result = find(n.right, key); return result; } public int getheight(Node root){ if (root == null) return 0; return Math.max(getheight(root.left), getheight(root.right)) + 1; } public void printTree(Node n) { if (n == null) return; printTree(n.left); n.displayNode(n); printTree(n.right); } } 

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 extends LinkedHashMap> { public void put(T[] path) { LinkedList list = new LinkedList<>(); for (T key : path) { list.add(key); } return put(list); } public void put(LinkedList path) { if (path.isEmpty()) { return; } T key = path.removeFirst(); TreeMap val = get(key); if (val == null) { val = new TreeMap<>(); put(key, val); } val.put(path); } } 

Il peut être utilisé pour stocker un arbre de choses de type “T” (générique), mais ne supporte pas (encore) 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 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.