0

I have been trying to implement a tree representation of Autosys job schedules at work. As each job(process) can have one or or more dependent job on them, i decided to go with a n-ary tree implementation so that i can map the flow. I an using java collections for the same.

Q1(Solved): The problem for now is that the display functions is getting hung up in a infinite loop. I tried looking for existing threads but could not come across examples for traversals using iterators.

Q2:(OPEN)The display function traverse the tree in a Post order manner. I would like to traverse it in a level order manner wherein the nodes get printed on level basis. Root, then all nodes on level one and then all nodes on level 2 and so on. The link for the DFS traversal is posted as another question at the link below. (Hi guys, I have another question for the level order traversal of the same tree, I have posted the question on the link given below. Would be gald if you guys could help. Level Order traversal of a generic tree(n-ary tree) in java Let us make this more resourceful for generic trees.)

Can we make this a resourceful post for people new with n-ary trees because I found very few elementary examples out there.

Here is my code where i have started with a root node with three children. I plan to expand this later.

One elementary question. Is using iterator in recursion not advised. I tried definig an Iterator separate in display() but it still didn't work.

Current Tree Structure:

     root(100)
    /      |       \
  90       50       70
  /        \
20 30   200  300

The output is in post order(not sure if that means DFS).

20 30 90 200 300 50 70 100

Code

import java.util.*;
import java.io.*;
import java.util.List;

//The node for the n-ary tree


public class NaryTree 
{
//The display function traverses the tree

void display(NaryTreeNode t)
{
    Iterator<NaryTreeNode> IT = t.nary_list.iterator();
    if(!(IT.hasNext()))   //If the node does not  have any children, enter.
    {
    //    System.out.println("No more childs of this node");
        System.out.print( t.data + " ");
        return;
    }

    while(IT.hasNext()){
        display(IT.next()) ;            //Recursive Call
    }

   System.out.print(t.data + " ");
}

public static void main(String args[]){

    NaryTree t1 = new NaryTree();

    NaryTreeNode root = new NaryTreeNode();

    root.data = 100;

    NaryTreeNode lev_11 = new NaryTreeNode();   lev_11.data=90;
    NaryTreeNode lev_12 = new NaryTreeNode();   lev_12.data=50;
    NaryTreeNode lev_13 = new NaryTreeNode();   lev_13.data=70;
    NaryTreeNode lev_21 = new NaryTreeNode();   lev_21.data=20;
    NaryTreeNode lev_22 = new NaryTreeNode();   lev_22.data=30;
    NaryTreeNode lev_23 = new NaryTreeNode();   lev_23.data=200;
    NaryTreeNode lev_24 = new NaryTreeNode();   lev_24.data=300;

    //Add all the nodes to a list.



    List<NaryTreeNode> temp2 = new ArrayList<NaryTreeNode>();  //Level two first branch
    temp2.add(lev_21);
    temp2.add(lev_22);

    List<NaryTreeNode> temp3 = new ArrayList<NaryTreeNode>();  //level two second branch
    temp3.add(lev_23);
    temp3.add(lev_24);

    List<NaryTreeNode> temp = new ArrayList<NaryTreeNode>();  //level one
    temp.add(lev_11);
    temp.add(lev_12);
    temp.add(lev_13);

    lev_11.nary_list.addAll(temp2);
    lev_12.nary_list.addAll(temp3);
    //Add Temp to root  to form a leaf of the root

    root.nary_list.addAll(temp);
    //Call the display function.
    t1.display(root);

} }

Community
  • 1
  • 1
Sameer
  • 757
  • 1
  • 14
  • 35
  • How can this compile? You are trying to add a `List` to just another `List`. I'd expect some exception! – Fildor Oct 06 '12 at 20:14
  • Correcting myself: It's a `addAll` and therefor correct. – Fildor Oct 06 '12 at 20:33
  • You should not change the code in your question. It will be confusing for people. Just accept the answer that worked. If you feel urged to, add another code block with the change. – Fildor Oct 06 '12 at 20:37
  • Explicitly defining an iterator solved the problem. – Sameer Oct 06 '12 at 20:48
  • Now the next issue is with the display function, it is not displaying the nodes in DFS or BFS manner. Do i open a new question for this or can I edit the same question. Please advise. – Sameer Oct 06 '12 at 21:10
  • When in a question an answer has been accepted, it is "done". You should open a new Question. – Fildor Oct 06 '12 at 21:34
  • @Sam, as Fildor says the correct SO process is to open a new question. The code in this question should illustrate the original problem, so readers can clearly see what was solved. However, the solution to your second problem consists of removing the condition and return, so the current node is displayed before iterating the children. Your output would then be DFS. http://en.wikipedia.org/wiki/Depth-first_search – Steven McGrath Oct 07 '12 at 03:28
  • Hi guys, I got stuck at the level order traversal of the same tree, I have posted the question on the link given below. Would be gald if you guys could help. http://stackoverflow.com/questions/12788641/level-order-traversal-of-a-generic-treen-ary-tree-in-java – Sameer Oct 08 '12 at 20:05

3 Answers3

3
nary_list.iterator()

Creates a new iterator every time. So if a list has anything inside it, this will be an infinite loop; it creates a new iterator every time it is run, and always has the element in it:

while(t.nary_list.iterator().hasNext()){

If you want to work with iterators directly, you could do this:

Iterator<NaryTreeNode> iterator = t.nary_list.iterator();
while (iterator.hasNext()) {

However, you can also use the for each loop in Java to make this less wordy:

for (NaryTreeNode node : t.nary_list) 

EDIT

I would also write the display function in this order, so that you print the value of the current node after exhausting the iterator, rather than having to ask !hasNext():

// Display all of my children
for (NaryTreeNode node : t.nary_list) {
    display(node);
}

// Display myself
System.out.println("Value is: " + t.data);
Cory Kendall
  • 7,195
  • 8
  • 37
  • 64
  • @Sam Another tip: You can directly add to the Node's List: `root.nary_list.add(lev_11);` You do not need an extra temp list and `addAll` – Fildor Oct 06 '12 at 20:41
  • 2
    @Sam I see you're new to the site; if you end up using my code please upvote and/or accept the answer (with the green checkmark to the left of the answer). It's our way of saying thanks :). – Cory Kendall Oct 06 '12 at 20:57
  • Guys, I added the next question to the post. Would appreciate if you could help. Please advise if i should open a new question. I wanted to keep this post as a reference to a elementary n-ary tree implementation. Thanks a ton! – Sameer Oct 06 '12 at 21:23
  • @CoryKendall Thanks for the edit, this is much more efficient. – Sameer Oct 08 '12 at 06:14
  • Hi guys, I got stuck at the level order traversal of the same tree, I have posted the question on the link given below. Would be gald if you guys could help. http://stackoverflow.com/questions/12788641/level-order-traversal-of-a-generic-treen-ary-tree-in-java – Sameer Oct 08 '12 at 20:05
2

It appears to me you are creating a fresh iterator each time through the loop, so each is set to the beginning of the list. I'll try to add the spec reference in a moment. Try:

    Iterator<NsryTreeNode> i = t.nary_list.iterator();
    while(i.hasNext()){
        display(t.nary_list.iterator().next()) ;            //Recursive Call
    }

You may want to look at http://docs.oracle.com/javase/tutorial/collections/interfaces/list.html . You may find the ListIterator to have value.

Steven McGrath
  • 1,717
  • 11
  • 20
  • ... **and** he's adding a `List` (namely "temp") to a `List`. I have doubts that it compiles! At least it **must** throw an exception at runtime? – Fildor Oct 06 '12 at 20:16
  • @Steven I tried this earlier (Iterator IT = t.nary_list.iterator();) well but it still ran to an infinite loop. – Sameer Oct 06 '12 at 20:18
  • @DonRoby The exact code given by OP? I don't believe that and am tempted to try it out against all that I know about Java generics. – Fildor Oct 06 '12 at 20:21
  • @Fildor It is a running code. But I have never used iterators for a nary tree. I only get one value for the child node and then it seems the iterator never increments. – Sameer Oct 06 '12 at 20:22
  • OK, I take everything back I said and apologize. There's also `addAll(Collection)` ... dough. – Fildor Oct 06 '12 at 20:27
  • @Fildor, If it compiles for you, can you upvote the question, I will have much more to ask as i build on this, very few references for n-ary trees available. – Sameer Oct 06 '12 at 20:27
2

I don't know enough Java to understand what might be going on in that loop but it looks suspicious to me; the way I read that, you're creating a new iterator every time through the loop.

I would also suggest you consider the option of using first-child/next-sibling instead of putting a list in every node. In this system, every node references (at most) two other nodes: its first child (if it has any children) and its next sibling (unless it is the last sibling of its parent). You can then walk the sibling list through the sibling lists to enumerate children nodes, and you don't end up with all the overhead of a variable length array in every node.

rici
  • 234,347
  • 28
  • 237
  • 341