简体   繁体   中英

Iterate n-levels of linked lists Java

I have a tree with nodes, and each node contains a list with nodes, and each node in those lists contain nodes... It can be 10 levels deep, with around 100 node objects.

I've tried to iterate to find all individual node objects but most guides covers binary trees.. It's just overwhelming. If anyone has some pseudo code or can point me in the right direction I would be very glad. Classes below (sorry about the bad formatting):

Node

public class Node {
    public String text;
    public LinkedList<Node> nodes;

    public Node() {
        this.nodes = new LinkedList<Node>();
    }

    public Node(String data) {
        this();
        this.text = data;
    }
}

Tree

public class Tree {
    public LinkedList<Node> nodes;
    public String text;

    public Tree() {
        nodes = new LinkedList<Node>();
    }

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

Program

public class Main {

    public static void main(String[] args) {

        LinkedList<Tree> trees = new LinkedList<Tree>();

        trees.add(new Tree("Root 1"));

        trees.get(0).nodes.add(new Node("Node 1"));
        trees.get(0).nodes.add(new Node("Node 2"));
        trees.get(0).nodes.add(new Node("Node 3"));

        trees.get(0).nodes.get(0).nodes.add(new Node("Node 1:Child 1"));
        trees.get(0).nodes.get(1).nodes.add(new Node("Node 2:Child 1"));
        trees.get(0).nodes.get(2).nodes.add(new Node("Node 3:Child 1"));

        for (Tree tree : trees) {
            tree.nodes.. // find all node-objects
        }
    }
}

This can be done by recursion. Since you have maximum depth of 10 and max elements = 100, recursion should not give any performance issues. Sample code to do this:

List<Node> flattenTree(List<Node> nodes){
    List<Node> allNodes=new LinkedList<>(nodes) ;
    for(Node node:nodes){
        {
           if(node.getNodes()!=null)
           allNodes.addAll(flattenTree(node.getNodes()));
        } 
     return allNodes;
    }

Call this using:

List<Node> allNodes = flattenTree(tree.getNodes);

allNodes will contain all the nodes of this tree.

You can do this by using recursion:

interface TreeOp {
    void apply(Tree tree);
}

...

void traverse(Tree tree, TreeOp op) {
    op.apply(tree);
    for (Tree child: tree.nodes) {
        traverse(child, op);
    }
}

...

for (Tree tree : trees) {
    traverse(tree, (tree) -> {
       doSomethingWith(tree);
    });
}

UPDATE:

Actually, you can use the Consumer interface instead of defining a new one:

void traverse(Tree tree, Consumer<Tree> op) {
    op.accept(tree);
    for (Tree child: tree.nodes) {
        traverse(child, op);
    }
}

UPDATE 2:

And traverse could be a method of Tree:

void traverse(Consumer<Tree> op) {
    op.accept(this);
    for (Tree child: nodes) {
        traverse(child, op);
    }
}

Just out of curiosity, what kind of problem would require a data structure like this?

Something like this in main should set you on the right track:

// set up the master list of all nodes and the list of unvisited nodes
// with the base tree's node.
List<Node> allTheNodes = new LinkedList<>();
allTheNodes.add(tree.node);
List<Node> unvisited = new LinkedList<>();
unvisited.add(tree.node);

while (!unvisited.isEmpty())
{
    // while our unvisited list is not empty, visit the first node in the list
    // and add all of its subnodes to both the list of nodes to visit and the master list of nodes.
    Node currentNode = unvisited.get(0);
    allTheNodes.addAll(currentNode.nodes);
    unvisited.addAll(currentNode.nodes);
    unvisited.remove(currentNode);
}   

// now, allTheNodes should have all of your nodes in it.

You just need to track the depth of the nodes:

LinkedList<Node> currentNodes = new LinkedList<Node>();
currentNodes.add(root);
int depth = 0;
while depth < 10 {
    depth++;
    int size = currentNodes.size();
    for (int i = 0; i < size; i++) {
        Node current = currentNodes.removeFirst();
        //Do something with current
        for (int j = 0; j < current.nodes.size(); j++) {
            currentNodes.addLast(current.nodes.get(j));
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM