Kronen
Kronen

Reputation: 476

Removing nodes without a particular subnode in a tree structure

I have a tree structure like this one:

public class Project {
    private String id;
    private String description;
    private List<Project> subProjects;
    private List<Document> documents;
}

List<Project> projects = new ArrayList<Project>;

The projects can have subprojects or documents but not both at the same time. My problem is trying to filter this list by removing from it every project or subproject which has no documents. So we remove the project if the project have no documents and no subprojects, or if none of his subprojects have documents.

Can it be done recursively?

Upvotes: 1

Views: 59

Answers (2)

phflack
phflack

Reputation: 2727

Straight interpretation of your conditions A. remove if subProjects and documents are empty or B. all children have no documents (assuming "none of his subprojects have documents" means all children, not just direct children)

Defining a boolean function often helps to check the status of a node, and then can query it to check if the node should be removed

The code assumes you're putting it in Project, if you're not you'll need to pass it as an argument

boolean isEmpty()
{
    return subProjects.isEmpty() && documents.isEmpty();
}

boolean isChildrenEmpty()
{
    //put before the recursion for speed
    if(!documents.isEmpty()) //check if self has documents
        return false;

    for(Project child : subProjects)
        if(!child.isChildrenEmpty()) //check if any child has documents
            return false;

    return true; //all children + self have no documents
}

boolean toRemove()
{
    if(isEmpty()) //no children, no documents
        return true;

    for(Project child : subProjects)
        if(!child.isChildrenEmpty()) //a child has a document
            return false;
    return true;
}

Upvotes: 1

Shihab Shahriar Khan
Shihab Shahriar Khan

Reputation: 5475

If you can guarantee a tree structure i.e no cycle, all you need is a simple post-order DFS.

If you don't want to modify your Project class, in filter function create a HashMap, (Key:project, Value: total documents in it's subtree.)

Now, map[P] = sum of all map[child] + number of documents in P when child is in P's subproject variable.

That's it really, even no edge condition check is required. It should work for any number of sub-projects or documents under P, including your condition when one of them must be 0.

Upvotes: 1

Related Questions