Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

algorithm to find nodes that lack children in single parent, multiple children graph

Imagine a data structure whereby you have a graph full of nodes.

Each node has data, a single parent and 0+ children.

class Node:
    def __init__(self, data) -> None:
        self.data = data
        self.parent = None
        self.children = []

The graph handles connecting the nodes as such

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

class Graph:
    def __init__(self, node) -> None:
        self.root_node = node

   def add_relationship(self, parent, child):
        if not parent.parent:
            parent.parent = self.root_node
            self.root_node.children.append(parent)

        parent.children.append(child)
        child.parent = parent

For constraints, lets say that there will be anywhere from 2 to 100 nodes total.

Now, let’s suppose I want to add a method to the graph class that returns all the nodes in the graph that do not have children.

My first thought is recursion.

def _end_nodes(self, current_node, nodes_with_children=[], nodes_without_children=[]):
    for node in current_node.children:
        if node.children:
            nodes_with_children.append(node)
        else:
            nodes_without_children.append(node)
    
    if not nodes_with_children:
        return []
    return [nodes_without_children] + self._end_nodes(nodes_with_children.pop(0))

But this yields the desired answer repeated however many times the recursive function is called.

Of course, I could just get a single element from the returned array

def __repr__(self) -> str:
    return str(self._end_nodes(self.root_node)[0])

But I feel like this is sloppy. How can I go about getting the desired results in a more succinct manner?

>Solution :

To find the nodes that lack children in a single parent, multiple children graph, you can add a method to the Graph class that traverses the entire graph and collects nodes without children.

The method is defined as below. Its basically using the BFS.

def find_nodes_without_children(self):
        nodes_without_children = []
        queue = [self.root_node]
        
        while queue:
            current_node = queue.pop(0)
            if not current_node.children:
                nodes_without_children.append(current_node)
            else:
                queue.extend(current_node.children)
        
        return nodes_without_children

and you can verify it from the line of code below

print([node.data for node in graph.find_nodes_without_children()])

Overall Implementation will looks something like below

    class Node:
    def __init__(self, data) -> None:
        self.data = data
        self.parent = None
        self.children = []

class Graph:
    def __init__(self, node) -> None:
        self.root_node = node

    def add_relationship(self, parent, child):
        if not parent.parent:
            parent.parent = self.root_node
            self.root_node.children.append(parent)
        parent.children.append(child)
        child.parent = parent

    def find_nodes_without_children(self):
        nodes_without_children = []
        queue = [self.root_node]
        
        while queue:
            current_node = queue.pop(0)
            if not current_node.children:
                nodes_without_children.append(current_node)
            else:
                queue.extend(current_node.children)
        
        return nodes_without_children

FYI: The both Time and Space complexity is O(N)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading