Baked Inhalf
Baked Inhalf

Reputation: 3735

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

Upvotes: 0

Views: 318

Answers (4)

Abhisar
Abhisar

Reputation: 186

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.

Upvotes: 2

Lajos Arpad
Lajos Arpad

Reputation: 76631

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

Upvotes: 1

Adil B
Adil B

Reputation: 16806

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.

Upvotes: 1

Maurice Perry
Maurice Perry

Reputation: 9650

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

Upvotes: 1

Related Questions