BOOM-implementatie in Java (root, ouders en kinderen)

Ik moet een boomstructuur maken die vergelijkbaar is als de bijgevoegde afbeelding in Java. Ik heb een aantal vragen gevonden met betrekking tot deze, maar ik heb geen overtuigend en goed uitgelegd antwoord gevonden.
Het toepassingsbedrijf bestaat uit voedsel supercategorieën (hoofdgerechten, desserts en andere). Elk van deze categorieën kan bovenliggende items of kinderartikelen enzovoort hebben.


Antwoord 1, Autoriteit 100%

import java.util.ArrayList;
import java.util.List;
public class Node<T> {
    private List<Node<T>> children = new ArrayList<Node<T>>();
    private Node<T> parent = null;
    private T data = null;
    public Node(T data) {
        this.data = data;
    }
    public Node(T data, Node<T> parent) {
        this.data = data;
        this.parent = parent;
    }
    public List<Node<T>> getChildren() {
        return children;
    }
    public void setParent(Node<T> parent) {
        parent.addChild(this);
        this.parent = parent;
    }
    public void addChild(T data) {
        Node<T> child = new Node<T>(data);
        child.setParent(this);
        this.children.add(child);
    }
    public void addChild(Node<T> child) {
        child.setParent(this);
        this.children.add(child);
    }
    public T getData() {
        return this.data;
    }
    public void setData(T data) {
        this.data = data;
    }
    public boolean isRoot() {
        return (this.parent == null);
    }
    public boolean isLeaf() {
        return this.children.size == 0;
    }
    public void removeParent() {
        this.parent = null;
    }
}

Voorbeeld:

import java.util.List;
Node<String> parentNode = new Node<String>("Parent"); 
Node<String> childNode1 = new Node<String>("Child 1", parentNode);
Node<String> childNode2 = new Node<String>("Child 2");     
childNode2.setParent(parentNode); 
Node<String> grandchildNode = new Node<String>("Grandchild of parentNode. Child of childNode1", childNode1); 
List<Node<String>> childrenNodes = parentNode.getChildren();

Antwoord 2, Autoriteit 68%

Geaccepteerd antwoord gooit een java.lang.StackOverflowErrorBij het bellen van de setParentof addChildMETHODEN.

Hier is een iets eenvoudiger implementatie zonder die bugs:

public class MyTreeNode<T>{
    private T data = null;
    private List<MyTreeNode> children = new ArrayList<>();
    private MyTreeNode parent = null;
    public MyTreeNode(T data) {
        this.data = data;
    }
    public void addChild(MyTreeNode child) {
        child.setParent(this);
        this.children.add(child);
    }
    public void addChild(T data) {
        MyTreeNode<T> newChild = new MyTreeNode<>(data);
        this.addChild(newChild);
    }
    public void addChildren(List<MyTreeNode> children) {
        for(MyTreeNode t : children) {
            t.setParent(this);
        }
        this.children.addAll(children);
    }
    public List<MyTreeNode> getChildren() {
        return children;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
    private void setParent(MyTreeNode parent) {
        this.parent = parent;
    }
    public MyTreeNode getParent() {
        return parent;
    }
}

Enkele voorbeelden:

MyTreeNode<String> root = new MyTreeNode<>("Root");
MyTreeNode<String> child1 = new MyTreeNode<>("Child1");
child1.addChild("Grandchild1");
child1.addChild("Grandchild2");
MyTreeNode<String> child2 = new MyTreeNode<>("Child2");
child2.addChild("Grandchild3");
root.addChild(child1);
root.addChild(child2);
root.addChild("Child3");
root.addChildren(Arrays.asList(
        new MyTreeNode<>("Child4"),
        new MyTreeNode<>("Child5"),
        new MyTreeNode<>("Child6")
));
for(MyTreeNode node : root.getChildren()) {
    System.out.println(node.getData());
}

Antwoord 3, autoriteit 7%

Hier is mijn implementatie in Java voor uw vereiste.
In de treeNode-klasse heb ik generieke arraygebruikt om de boomgegevens op te slaan. we kunnen ook arraylistof dynamische arraygebruiken om de boomwaarde op te slaan.

public class TreeNode<T> {
   private T value = null;
   private TreeNode[] childrens = new TreeNode[100];
   private int childCount = 0;
    TreeNode(T value) {
        this.value = value;
    }
    public TreeNode addChild(T value) {
        TreeNode newChild = new TreeNode(value, this);
        childrens[childCount++] = newChild;
        return newChild;
    }
    static void traverse(TreeNode obj) {
        if (obj != null) {
            for (int i = 0; i < obj.childCount; i++) {
                System.out.println(obj.childrens[i].value);
                traverse(obj.childrens[i]);
            }
        }
        return;
    }
    void printTree(TreeNode obj) {
        System.out.println(obj.value);
        traverse(obj);
    }
}

En de clientklasse voor de bovenstaande implementatie.

public class Client {
    public static void main(String[] args) {
        TreeNode menu = new TreeNode("Menu");
        TreeNode item = menu.addChild("Starter");
            item = item.addChild("Veg");
                item.addChild("Paneer Tikka");
                item.addChild("Malai Paneer Tikka");
            item = item.addChild("Non-veg");
                item.addChild("Chicken Tikka");
                item.addChild("Malai Chicken Tikka");
        item = menu.addChild("Main Course");
            item = item.addChild("Veg");
                item.addChild("Mili Juli Sabzi");
                item.addChild("Aloo Shimla Mirch");
            item = item.addChild("Non-veg");
                item.addChild("Chicken Do Pyaaza");
                item.addChild("Chicken Chettinad");
        item = menu.addChild("Desserts");
                item = item.addChild("Cakes");
                        item.addChild("Black Forest");
                        item.addChild("Black Current");
                item = item.addChild("Ice Creams");
                        item.addChild("chocolate");
                        item.addChild("Vanilla");
        menu.printTree(menu);
    }
}

UITVOER

Menu                                                                     
Starter                                                                 
Veg                                                                
Paneer Tikka                                                        
Malai Paneer Tikka                                                    
Non-veg                                                              
Chicken Tikka                                                      
Malai Chicken Tikka                                                 
Main Course                                                      
Veg                                                             
Mili Juli Sabzi                                                   
Aloo Shimla Mirch                                                  
Non-veg                                                               
Chicken Do Pyaaza                                                   
Chicken Chettinad                                                    
Desserts                                                         
Cakes                                                            
Black Forest                                                     
Black Current                                                   
Ice Creams                                                      
chocolate                                                       
Vanilla           

Antwoord 4, Autoriteit 2%

Sinds @jonathan ‘s Antwoord bestond nog steeds uit sommige bugs, ik heb een verbeterde versie gemaakt. Ik overschrijft de toString()-methode voor foutopsporingsdoeleinden, zorg ervoor dat u het dienovereenkomstig aan uw gegevens verandert.

import java.util.ArrayList;
import java.util.List;
/**
 * Provides an easy way to create a parent-->child tree while preserving their depth/history.
 * Original Author: Jonathan, https://stackoverflow.com/a/22419453/14720622
 */
public class TreeNode<T> {
    private final List<TreeNode<T>> children;
    private TreeNode<T> parent;
    private T data;
    private int depth;
    public TreeNode(T data) {
        // a fresh node, without a parent reference
        this.children = new ArrayList<>();
        this.parent = null;
        this.data = data;
        this.depth = 0; // 0 is the base level (only the root should be on there)
    }
    public TreeNode(T data, TreeNode<T> parent) {
        // new node with a given parent
        this.children = new ArrayList<>();
        this.data = data;
        this.parent = parent;
        this.depth = (parent.getDepth() + 1);
        parent.addChild(this);
    }
    public int getDepth() {
        return this.depth;
    }
    public void setDepth(int depth) {
        this.depth = depth;
    }
    public List<TreeNode<T>> getChildren() {
        return children;
    }
    public void setParent(TreeNode<T> parent) {
        this.setDepth(parent.getDepth() + 1);
        parent.addChild(this);
        this.parent = parent;
    }
    public TreeNode<T> getParent() {
        return this.parent;
    }
    public void addChild(T data) {
        TreeNode<T> child = new TreeNode<>(data);
        this.children.add(child);
    }
    public void addChild(TreeNode<T> child) {
        this.children.add(child);
    }
    public T getData() {
        return this.data;
    }
    public void setData(T data) {
        this.data = data;
    }
    public boolean isRootNode() {
        return (this.parent == null);
    }
    public boolean isLeafNode() {
        return (this.children.size() == 0);
    }
    public void removeParent() {
        this.parent = null;
    }
    @Override
    public String toString() {
        String out = "";
        out += "Node: " + this.getData().toString() + " | Depth: " + this.depth + " | Parent: " + (this.getParent() == null ? "None" : this.parent.getData().toString()) + " | Children: " + (this.getChildren().size() == 0 ? "None" : "");
        for(TreeNode<T> child : this.getChildren()) {
            out += "\n\t" + child.getData().toString() + " | Parent: " + (child.getParent() == null ? "None" : child.getParent().getData());
        }
        return out;
    }
}

En voor de visualisatie:

import model.TreeNode;
/**
 * Entrypoint
 */
public class Main {
    public static void main(String[] args) {
        TreeNode<String> rootNode = new TreeNode<>("Root");
        TreeNode<String> firstNode = new TreeNode<>("Child 1 (under Root)", rootNode);
        TreeNode<String> secondNode = new TreeNode<>("Child 2 (under Root)", rootNode);
        TreeNode<String> thirdNode = new TreeNode<>("Child 3 (under Child 2)", secondNode);
        TreeNode<String> fourthNode = new TreeNode<>("Child 4 (under Child 3)", thirdNode);
        TreeNode<String> fifthNode = new TreeNode<>("Child 5 (under Root, but with a later call)");
        fifthNode.setParent(rootNode);
        System.out.println(rootNode.toString());
        System.out.println(firstNode.toString());
        System.out.println(secondNode.toString());
        System.out.println(thirdNode.toString());
        System.out.println(fourthNode.toString());
        System.out.println(fifthNode.toString());
        System.out.println("Is rootNode a root node? - " + rootNode.isRootNode());
        System.out.println("Is firstNode a root node? - " + firstNode.isRootNode());
        System.out.println("Is thirdNode a leaf node? - " + thirdNode.isLeafNode());
        System.out.println("Is fifthNode a leaf node? - " + fifthNode.isLeafNode());
    }
}

Voorbeelduitgang:

Node: Root | Depth: 0 | Parent: None | Children: 
    Child 1 (under Root) | Parent: Root
    Child 2 (under Root) | Parent: Root
    Child 5 (under Root, but with a later call) | Parent: Root
Node: Child 1 (under Root) | Depth: 1 | Parent: Root | Children: None
Node: Child 2 (under Root) | Depth: 1 | Parent: Root | Children: 
    Child 3 (under Child 2) | Parent: Child 2 (under Root)
Node: Child 3 (under Child 2) | Depth: 2 | Parent: Child 2 (under Root) | Children: 
    Child 4 (under Child 3) | Parent: Child 3 (under Child 2)
Node: Child 4 (under Child 3) | Depth: 3 | Parent: Child 3 (under Child 2) | Children: None
Node: Child 5 (under Root, but with a later call) | Depth: 1 | Parent: Root | Children: None
Is rootNode a root node? - true
Is firstNode a root node? - false
Is thirdNode a leaf node? - false
Is fifthNode a leaf node? - true

Enkele aanvullende informatie: Gebruik geen addChildren()en setParent()SAMEN. Je hebt uiteindelijk twee referenties als setParent()Reeds update van de kinderen = & GT; ouderrelatie.


Antwoord 5

Deze boom is geen binaire boom, dus je hebt een reeks van de elementen van kinderen, zoals lijst nodig.

public Node(Object data, List<Node> children) {
    this.data = data;
    this.children = children;
}

Maak vervolgens de instanties.


Antwoord 6

In het geaccepteerde antwoord

public Node(T data, Node<T> parent) {
    this.data = data;
    this.parent = parent;
}

moet

zijn

public Node(T data, Node<T> parent) {
    this.data = data;
    this.setParent(parent);
}

Anders heeft de ouder het kind niet in de lijst met kinderen


Antwoord 7

in Antwoord
, het creëert cirkelvormige afhankelijkheid. Dit kan worden vermeden door het verwijderen van ouder binnen kinderknooppunten.
I.E,

public class MyTreeNode<T>{     
    private T data = null;
    private List<MyTreeNode> children = new ArrayList<>();
    public MyTreeNode(T data) {
        this.data = data;
    }
    public void addChild(MyTreeNode child) {
        this.children.add(child);
    }
    public void addChild(T data) {
        MyTreeNode<T> newChild = new MyTreeNode<>(data);
        children.add(newChild);
    }
    public void addChildren(List<MyTreeNode> children) {
        this.children.addAll(children);
    }
    public List<MyTreeNode> getChildren() {
        return children;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
}

Gebruik van hetzelfde hierboven gespecificeerde voorbeeld, is de uitvoer zo:

{“gegevens”: “root”, “kinderen”: [
{
“Gegevens”: “Child1”,
“kinderen”: [
{
“data”: “Kleinkind1”,
“kinderen”: []
},
{
“data”: “Kleinkind2”,
“kinderen”: []
}
]
},
{
“gegevens”: “Kind2”,
“kinderen”: [
{
“data”: “Kleinkind3”,
“kinderen”: []
}
]
},
{
“gegevens”: “Kind3”,
“kinderen”: []
},
{
“gegevens”: “Kind4”,
“kinderen”: []
},
{
“gegevens”: “Kind5”,
“kinderen”: []
},
{
“gegevens”: “Kind6”,
“kinderen”: []
} ] }


Antwoord 8

Het proces van het samenstellen van boomknooppunten is vergelijkbaar met het proces van het samenstellen van lijsten. We hebben een constructor voor boomknooppunten die de instantievariabelen initialiseert.

public Tree (Object cargo, Tree left, Tree right) { 
    this.cargo = cargo; 
    this.left = left; 
    this.right = right; 
} 

We wijzen eerst de onderliggende nodes toe:

Tree left = new Tree (new Integer(2), null, null); 
Tree right = new Tree (new Integer(3), null, null); 

We kunnen het bovenliggende knooppunt maken en het tegelijkertijd aan de kinderen koppelen:

Tree tree = new Tree (new Integer(1), left, right); 

Other episodes