it-swarm.com.de

Java Baumdatenstruktur?

Gibt es eine gute verfügbare (Standard Java) Datenstruktur, um einen Baum in Java darzustellen?

Konkret muss ich folgendes darstellen:

  • Der Baum an jedem Knoten kann eine beliebige Anzahl von Kindern haben
  • Jeder Knoten (nach dem Stamm) ist nur eine Zeichenfolge (deren untergeordnete Elemente ebenfalls Zeichenfolgen sind).
  • Ich muss in der Lage sein, alle Kinder (irgendeine Art Liste oder Array von Strings) mit einer Eingabezeichenfolge zu versehen, die einen bestimmten Knoten darstellt

Gibt es eine verfügbare Struktur dafür oder muss ich eine eigene erstellen (wenn ja, wären Implementierungsvorschläge großartig).

479
ikl

Hier:

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;
    }
}

Dies ist eine grundlegende Baumstruktur, die für String oder jedes andere Objekt verwendet werden kann. Es ist ziemlich einfach, einfache Bäume zu implementieren, um das zu tun, was Sie brauchen.

Alles, was Sie hinzufügen müssen, sind Methoden zum Hinzufügen, Entfernen, Durchlaufen und Konstruieren. Das Node ist der Grundbaustein des Tree.

292
jjnguy

Noch eine andere Baumstruktur:

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 ...

}

Beispielnutzung:

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
Siehe vollwertigen Baum mit:

  • iterator
  • suche
  • Java/C #

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

115
Grzegorz Dev

Tatsächlich ist im JDK eine ziemlich gute Baumstruktur implementiert.

Schauen Sie sich javax.swing.tree , TreeModel und TreeNode an. Sie sind für die Verwendung mit JTreePanel konzipiert, aber sie sind in der Tat eine ziemlich gute Baumimplementierung, und nichts hindert Sie daran, sie ohne Swing-Schnittstelle zu verwenden.

Beachten Sie, dass Sie diese Klassen ab Java 9 möglicherweise nicht mehr verwenden möchten, da sie in 'Compact profiles' nicht mehr vorhanden sind.

97
Gareth Davis

Was ist damit?

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 wrote eine kleine Bibliothek, die mit generischen Bäumen umgeht. Es ist viel leichter als das Swingzeug. Ich habe auch ein Maven-Projekt dafür.

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;
    }
}

Natürlich können Sie Dienstprogrammmethoden hinzufügen, um Kinder hinzuzufügen/zu entfernen.

17
PaulJWilliams

Sie sollten zunächst definieren, was ein Baum ist (für die Domäne). Dies geschieht am besten, indem Sie zuerst Schnittstelle definieren. Nicht alle Baumstrukturen können geändert werden. Die Angabe von add und remove Knoten sollte eine optionale Funktion sein. Daher erstellen wir eine zusätzliche Schnittstelle.

Es ist nicht erforderlich, Knotenobjekte zu erstellen, die die Werte enthalten. Tatsächlich sehe ich dies in den meisten Baumimplementierungen als großen Konstruktionsfehler und Overhead an. Wenn Sie Swing betrachten, ist TreeModel frei von Knotenklassen (nur DefaultTreeModel verwendet TreeNode), da sie nicht wirklich benötigt werden.

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

Veränderbare Baumstruktur (erlaubt das Hinzufügen und Entfernen von Knoten):

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

Angesichts dieser Schnittstellen muss sich Code, der Bäume verwendet, nicht viel darum kümmern, wie der Baum implementiert wird. Auf diese Weise können Sie generische Implementierungen sowie spezialisierte verwenden, um den Baum zu realisieren, indem Sie Funktionen an eine andere API delegieren.

Beispiel: Dateibaumstruktur

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();
    }
}

Beispiel: generische Baumstruktur (basierend auf Eltern/Kind-Beziehungen):

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

Keine Antwort erwähnt einen zu vereinfachten, aber funktionierenden Code. Hier ist es also:

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

Sie können jede XML-API von Java als Dokument und Knoten verwenden. XML ist eine Baumstruktur mit Zeichenfolgen

10

Wenn Sie Whiteboard-Codierung, ein Interview oder auch nur die Verwendung eines Baums planen, ist die Ausführlichkeit dieser Informationen ein wenig zu groß.

Es sollte weiter gesagt werden, dass der Grund, warum ein Baum nicht dort ist, wie zum Beispiel ein Pair (wovon dasselbe gesagt werden könnte), ist, dass Sie Ihre Daten in der Klasse einkapseln sollten, die ihn verwendet. nd Die einfachste Implementierung sieht folgendermaßen aus:

/***
/* 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;
}

Das ist es wirklich für einen Baum beliebiger Breite.

Wenn Sie einen Binärbaum haben möchten, ist die Verwendung mit benannten Feldern oft einfacher:

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

Oder wenn Sie einen Versuch wollten:

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

Jetzt hast du gesagt, dass du willst

in der Lage zu sein, alle untergeordneten Elemente (eine Art Liste oder ein Array von Zeichenfolgen) mit einer Eingabezeichenfolge zu versehen, die einen bestimmten Knoten darstellt

Das klingt nach Hausaufgaben.
Aber da ich mir ziemlich sicher bin, dass jetzt eine Frist abgelaufen ist ...

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()));
 }
}

Das bekommt man wie folgt zu gebrauchen:

$ 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

In Java gibt es einige Baumdatenstrukturen, z. B. DefaultMutableTreeNode in JDK Swing, das Parserpaket Tree in Stanford und andere Spielzeugcodes. Aber keines davon ist ausreichend und dennoch klein genug für allgemeine Zwecke.

Java-Baum Das Projekt versucht, eine andere universelle Baumdatenstruktur in Java bereitzustellen. Der Unterschied zwischen diesem und anderen ist

  • Total frei. Sie können es überall verwenden (außer in Ihren Hausaufgaben: P)
  • Klein aber allgemein genug. Ich habe die gesamte Datenstruktur in einer Klassendatei abgelegt, sodass das Kopieren und Einfügen einfach ist.
  • Nicht nur ein Spielzeug. Mir sind Dutzende von Java Baumcodes bekannt, die nur Binärbäume oder eingeschränkte Operationen verarbeiten können. Dieser TreeNode ist viel mehr als das. Es bietet verschiedene Möglichkeiten, Knoten zu besuchen, wie z. B. Vorbestellung, Nachbestellung, Breite zuerst, Blätter, Pfad zur Wurzel usw. Außerdem werden auch Iteratoren zur Verfügung gestellt, damit dies ausreicht.
  • Weitere Tools werden hinzugefügt. Ich bin bereit, weitere Operationen hinzuzufügen, um dieses Projekt umfassend zu gestalten, insbesondere wenn Sie eine Anfrage über github senden.
7
Yifan Peng

Schauen Sie sich DefaultMutableTreeNode an, ähnlich wie Gareths Antwort. Es ist nicht generisch, scheint aber ansonsten die Rechnung zu passen. Obwohl es im javax.swing-Paket enthalten ist, hängt es nicht von AWT- oder Swing-Klassen ab. Tatsächlich hat der Quellcode tatsächlich den Kommentar // 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;
  }
}

So einfach wie es nur geht und so einfach zu bedienen. Um es zu benutzen, verlängern Sie es:

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

Da in der Frage nach einer verfügbaren Datenstruktur gefragt wird, kann ein Baum aus Listen oder Arrays erstellt werden:

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

instanceof kann verwendet werden, um zu bestimmen, ob ein Element ein Teilbaum oder ein Endknoten ist.

5
Olathe

Ich habe eine kleine "TreeMap" -Klasse geschrieben, die auf "HashMap" basiert und das Hinzufügen von Pfaden unterstützt:

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);
    }

}

Es kann verwendet werden, um einen Baum von Dingen des Typs "T" (generisch) zu speichern, unterstützt jedoch (noch) nicht das Speichern zusätzlicher Daten in seinen Knoten. Wenn Sie eine Datei wie diese haben:

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

Dann können Sie daraus einen Baum machen, indem Sie Folgendes ausführen:

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

Und du bekommst einen schönen Baum. Es sollte einfach sein, sich an Ihre Bedürfnisse anzupassen.

3
mevdschee

In der Vergangenheit habe ich dafür eine verschachtelte Karte verwendet. Dies ist, was ich heute benutze, es ist sehr einfach, aber es entspricht meinen Bedürfnissen. Vielleicht hilft das einem anderen.

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

Beispielsweise :

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

Sie können die in Apache JMeter enthaltene Klasse HashTree verwenden, die Teil des Jakarta-Projekts ist.

Die HashTree-Klasse ist im Paket org.Apache.jorphan.collections enthalten. Obwohl dieses Paket nicht außerhalb des JMeter-Projekts veröffentlicht wird, können Sie es problemlos herunterladen:

1) Laden Sie die JMeter-Quellen herunter.

2) Erstellen Sie ein neues Paket.

3) Kopieren Sie darauf/src/jorphan/org/Apache/jorphan/collections /. Alle Dateien außer Data.Java

4) Kopieren Sie auch /src/jorphan/org/Apache/jorphan/util/JOrphanUtils.Java

5) HashTree ist einsatzbereit.

2
David

Es gibt keine spezifische Datenstruktur in Java, die Ihren Anforderungen entspricht. Ihre Anforderungen sind sehr spezifisch und dafür müssen Sie Ihre eigene Datenstruktur entwerfen. Mit Blick auf Ihre Anforderungen kann jeder sagen, dass Sie eine Art n-ary-Baum mit einer bestimmten Funktionalität benötigen. Sie können Ihre Datenstruktur folgendermaßen gestalten:

  1. Die Struktur des Baumknotens entspricht dem Inhalt des Knotens und der Liste der untergeordneten Elemente wie folgt: class Node {String value; Liste Kinder;}
  2. Sie müssen die untergeordneten Elemente einer bestimmten Zeichenfolge abrufen, damit Sie über 2 Methoden 1 verfügen können: Node searchNode (String str) gibt den Knoten zurück, der denselben Wert wie die angegebene Eingabe hat (verwenden Sie BFS zum Suchen). 2: List getChildren (String str): Diese Methode ruft intern den searchNode auf, um den Knoten mit derselben Zeichenfolge abzurufen, und erstellt dann die Liste aller Zeichenfolgenwerte von untergeordneten Elementen und gibt sie zurück.
  3. Sie müssen außerdem eine Zeichenfolge in den Baum einfügen. Sie müssen eine Methode schreiben, z. B. void insert (String parent, String value): Dadurch wird der Knoten mit dem Wert parent erneut durchsucht. Anschließend können Sie einen Node mit dem angegebenen Wert erstellen und zur Liste hinzufügen von Kindern zum gefundenen Elternteil.

Ich würde vorschlagen, Sie schreiben die Struktur des Knotens in einer Klasse wie Class Node {String value; Listen Sie untergeordnete Elemente;} und alle anderen Methoden wie search, insert und getChildren in einer anderen NodeUtils-Klasse auf, damit Sie auch den Stamm des Baums übergeben können, um Operationen an bestimmten Bäumen auszuführen, z. B .: class NodeUtils {public static Node search ( Knotenstamm, Zeichenfolgenwert) {// BFS ausführen und Knoten zurückgeben}

2
aman rastogi

Ich habe eine Baumbibliothek geschrieben, die gut mit Java8 zusammenarbeitet und keine weiteren Abhängigkeiten aufweist. Es bietet auch eine lockere Interpretation einiger Ideen aus der funktionalen Programmierung und ermöglicht das Zuordnen/Filtern/Beschneiden/Durchsuchen des gesamten Baums oder der Unterbäume.

https://github.com/RutledgePaulV/Prune

Die Implementierung hat keine besonderen Auswirkungen auf die Indizierung, und ich habe mich nicht von der Rekursion abgewandt. Daher ist es möglich, dass die Leistung bei großen Bäumen abnimmt und Sie den Stack sprengen können. Wenn Sie jedoch nur einen einfachen Baum mit geringer bis mittlerer Tiefe benötigen, funktioniert er meiner Meinung nach gut genug. Es bietet eine vernünftige (wertebasierte) Definition von Gleichheit und eine toString-Implementierung, mit der Sie den Baum visualisieren können!

2
RutledgePaulV

Bitte überprüfen Sie den folgenden Code, in dem ich Tree-Datenstrukturen verwendet habe, ohne Collection-Klassen zu verwenden. Der Code kann Bugs/Verbesserungen enthalten. Verwenden Sie diesen Code jedoch nur als Referenz

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

Sie können die TreeSet-Klasse in Java.util. * Verwenden. Es funktioniert wie ein binärer Suchbaum, ist also bereits sortiert. Die TreeSet-Klasse implementiert die Schnittstellen Iterable, Collection und Set. Sie können den Baum mit einem Iterator wie eine Menge durchlaufen.

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

Sie können überprüfen, Java Doc und einige andere .

1
Oguz