Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8648541
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T13:20:12+00:00 2026-06-12T13:20:12+00:00

For a tree structure as follows public class Node implements Comparable<Node> { private List<Node>

  • 0

For a tree structure as follows

public class Node implements Comparable<Node> {
    private List<Node> nodes=new ArrayList<Node>();
    private String name="";
    private List<String> leaves=new ArrayList<String>();
    private Node parent=null;

    public List<Node> getNodes() {
        return nodes;
    }

    public void setNodes(List<Node> nodes) {
        this.nodes = nodes;
    }

    public List<String> getLeaves() {
        return leaves;
    }

    public void setLeaves(List<String> leaves) {
        this.leaves = leaves;
    }

    @Override
    public int compareTo(Node o) {
        return this.getName().compareTo(o.getName());
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Node getParent() {
        return parent;
    }

    public void setParent(Node parent) {
        this.parent = parent;
    }

    public int getDepth() {
        int depth = 0;
        Node parent = this.getParent();
        while (parent != null) {
            depth++;
            parent = parent.getParent();
        }
        return depth;
    }
}

From a node, I wish to have a method that returns all the distinct direct and indirect leaves (In the above case the strings leaves would be the leaves), for that node in sorted order.

Above is a highly torn down data structure to easy testing and demonstration. I have tried the following 3 approaches,

Approach A
Very slow when depth is large ~20, since the deepest leaves are traversed to several times, once for each of its ancestor, hence same path is traversed multiple times.

    public List<String> getLeavesDeep1() {
        Set<String> leaves = new TreeSet<String>();
        leaves.addAll(getLeaves());
        for (Node node : getNodes()) {
            leaves.addAll(node.getLeavesDeep1());
        }
        return new ArrayList<String>(leaves);
    }

Avg: 12694 ms / Without sort/distinct> Avg: 471 ms

Approach B
Little faster than A, as the number of nodes is comparatively very less than leaves, so using the approach A but for nodes, and then for each of the nodes, getting direct leaves only.

    private List<Node> getNodesDeep2() {
        Set<Node> nodes = new TreeSet<Node>();
        nodes.addAll(getNodes());
        for (Node node : getNodes()) {
            nodes.addAll(node.getNodesDeep2());
        }
        return new ArrayList<Node>(nodes);
    }

    public List<String> getLeavesDeep2() {
        Set<String> leaves = new TreeSet<String>();
        leaves.addAll(getLeaves());
        for (Node node : getNodesDeep2()) {
            leaves.addAll(node.getLeaves());
        }
        return new ArrayList<String>(leaves);
    }

Avg: 4355 ms / Without sort/distinct> Avg: 2406 ms

Approach C
Avoid TreeSet, used ArrayList’s and sorted & filtered (not the best way to sort/distinct though) just before returning

    private List<Node> getNodesDeep3() {
        List<Node> nodes = new ArrayList<Node>();
        nodes.addAll(getNodes());
        for (Node node : getNodes()) {
            nodes.addAll(node.getNodesDeep3());
        }
        return new ArrayList<Node>(new TreeSet<Node>(nodes));
    }

    public List<String> getLeavesDeep3() {
        List<String> leaves = new ArrayList<String>();
        leaves.addAll(getLeaves());
        for (Node node : getNodesDeep3()) {
            leaves.addAll(node.getLeaves());
        }
        return new ArrayList<String>(new TreeSet<String>(leaves));
    }

Avg: 4400

Looking for something faster, I know there are certain tree traversals that can be used, but I would prefer something simpler if there exists. P.S. These is no use case for searching at the moment. In my real class the times are much higher approx 3x to the above cases, as the structure is much more complex with the leaves not being simple strings, but POJOs

Following is the test I have used to get the times

private static final int NODES = 5;
private static final int LEAVES = 25;
private static final int DEPTH = 8;

public void addChildren(Node parent) {
    List<Node> nodes = new ArrayList<Node>();
    List<String> leaves = new ArrayList<String>();
    for (int i = 0; i < LEAVES; i++) {
        leaves.add(String.format("%s_leaf_%s", parent.getName(), i));
    }
    for (int i = 0; i < NODES; i++) {
        Node child = new Node();
        child.setParent(parent);
        child.setName(String.format("%s_%s", parent.getName(), i));
        nodes.add(child);
        if (child.getDepth() < DEPTH) {
            addChildren(child);
        }
    }
    parent.setNodes(nodes);
    parent.setLeaves(leaves);
}

@Test
public void testCase() {
    long start, tot=0;
    long t = 0;
    List<String> leaves;
    Node target = new Node();
    target.setName("Root");
    addChildren(target);
    for (int i = 0; i < 10; i++) {
        start = System.currentTimeMillis();
        leaves = target.getLeavesDeep5();
        t = System.currentTimeMillis() - start;
        tot += t;
        System.out.println(leaves.size() + " " + t);
    }

    System.out.println("Avg: " + (tot / 10));
}

Answers in any language are acceptable including pseudo code, as long as it doesn’t tightly tie the solution to that language (Exception: Pure java code is barred from the second clause)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-12T13:20:13+00:00Added an answer on June 12, 2026 at 1:20 pm

    I ran your test and it gave me the following results (i used your version 3, one slightly modified version3 and a new version)

    2441400 8038
    ...
    2441400 7890
    Avg: 7872
    
    2441400 4850
    ...
    2441400 3990
    Avg: 4165
    
    2441400 980
    ...
    2441400 710
    Avg: 786
    

    I first changed

    return new ArrayList<String>(new TreeSet<String>(leaves));
    

    to

    Collections.sort(leaves);
    return leaves;
    

    See Is it faster to add to a collection then sort it, or add to a sorted collection?

    Which gave an almost 50% reduction in execution time.
    Note: The TreeSet will remove duplicates, sort will not.

    I then wrote a new Iterator method combining your 2 methods into one and eliminating recursion all together. I also got rid of ArrayLists to avoid the resizing and copying which we don’t need because we only iterate and never access by index.

    Edit: using ArrayList to store the leaves increases time from 800ms to about 1400ms.

    public List<String> getLeavesDeepX()
    {
        final Deque<Node> nodes = new LinkedList<Node>();
        final Collection<String> leaves = new LinkedList<String>();
        //final Collection<String> leaves = new LinkedHashSet<String>(); -- use for removing dupes
        nodes.add(this);
        do
        {
            final Node current = nodes.pop();
            leaves.addAll(current.getLeaves());
            nodes.addAll(current.getTreeNodes());
        }
        while(nodes.isEmpty() == false);
    
        final ArrayList<String> result = new ArrayList<String>(leaves);
        Collections.sort(result);
        return result;
    }
    

    I put all results into different lists and compared those at the end.

        System.out.println(Arrays.equals(leaves1.toArray(), leaves2.toArray()));
        System.out.println(Arrays.equals(leaves1.toArray(), leaves3.toArray()));
        System.out.println(Arrays.equals(leaves2.toArray(), leaves3.toArray()));
    

    Output:

    true
    true
    true
    

    So at least on my system its about a 10 fold increase in speed.

    Edit2: Skipping the sorting in case 3 brings it to 140ms. So 600ms are used comparing and sorting. Any further major improvement needs to be done there.

    Edit3: Eliminating recursion also has the benefit that the depth of the tree has less impact on performance. Changing the TestTree to 2/2/20 (N/L/D) yields about the same number of leaves(2m) but performs much worse with recursion (>70k) but is not much slower (2500 from 1200) without.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I got a simple tree structure which contains the following public class MyTree {
I have a tree structure where each Node has a parent and a Set<Node>
Given the following tree structure in Haskell: data Tree = Leaf Int | Node
Let's say I have a binary tree data structure defined as follows type 'a
How would you implement in Java the binary tree node class and the binary
I've created a structure in Sitecore's content tree as follows : A Home root
I have a large Quad Tree structure, made from generic lists ( List<T> )
Let's say you have a tree structure as follows: a [Level 0] / |
Hi my required tree structure is as follows a -- b -- d |
I have a hierarchical (tree structure) SQL Server table TEmployee with following columns Id

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.