iterate through recursive objects

前端 未结 5 1582
孤独总比滥情好
孤独总比滥情好 2021-01-29 14:54

I am trying to iterate through a recursive object but Java has no support for this from what I know.

For example, given the object Item:

pub         


        
相关标签:
5条回答
  • 2021-01-29 15:30

    If you don't have cycles within the parent-child tree you can use a simple recursive function to determine the number of descendants:

    public class Item {
        ...
    
        public int getDescendantCount() {
            int count = 0;
            if (children != null) {
                 count += children.size();
                 for (Item child : children)
                      count += child.getDescendantCount();
            }
            return count;
        }
    }
    
    0 讨论(0)
  • 2021-01-29 15:32

    If the tree is very deep, use a breath-first search as suggested by Eran. If the tree is very wide, use a depth-first search which could look something like:

    class ItemVisitor { 
        public void accept(Item item) {
            // Do something
            for (Item i : item.getChildren()) {
                this.accept(i);
            }
        }
    }
    

    EDIT:

    For a breath-first search, use a queue and append all the children of the current node onto it.

    public void visitTree(Item head) {
        Queue<Item> queue = new PriorityQueue<Item>();
        while (queue.size() > 0) {
            Item curr = queue.poll();
            // Do something
            for (Item i : curr.getChildren())
                queue.add(i);
        }
    }
    
    0 讨论(0)
  • 2021-01-29 15:32

    If you can store depth as a separate data item and enforce it via class design/encapsulation, you're good there.

    What you're proposing is a node of some kind of tree of indeterminate depth. You can implement any normal depth-first or breadth-first search method; look it up in any standard data structures and algorithms textbook/web reference and implement in Java. The solution Eran posted while I was typing is a standard depth-first search if you use a Stack (last-in-first-out or LIFO queue), or a breadth-first search if you use a FIFO queue. These are nice and clean methods, but not the simplest.

    The most naïve method would be a simple recursive function for a depth-first search:

    public void recurseIntoChildren(Item item) {
        if(item.children.size() == 0) {
            // you are now at a leaf node: do something
        }
        for(Item child : item.children) {
            recurseIntoChildren(child);
        }
    }
    

    This form assumes you want to do something at leaf nodes. If you are searching for something, you can have recurseIntoChildren() return a special value when you find what you want so you can break out of all the rest of the recursive loops (let it return null or some other value to indicate the loop should continue). If you want to take other action, up to you to work this to your needs.

    This is not the most efficient method (unless the compiler optimises tail recursion into a simple loop).

    0 讨论(0)
  • 2021-01-29 15:37

    Something similar to this?

    void read(Item item) {
        if (item == null) {
            //do something with the uuid ?
            return;
        } else {
            for (Item i : item.children) {
                read(i);
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-29 15:40

    I don't know what the exact goal of the function is, but you can always loop recursively through children.

    For example

     public void loopChildren(List<Item> items) {
         for (Item i : items) {
             System.out.println(i.uuid);
             loopChildren(i.children);           
         }       
     }
    

    It just keep looping until the end of the list. If a child has no children List should be empty so it terminates for that iteration.

    Hope this helps.

    0 讨论(0)
提交回复
热议问题