Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm to find the max width of a tree, not using node structures

I'm trying to figure out how to calculate the max width of a tree. Instead of using a typical leaf/node structure, I am basing it on data from a DB. I will find all the children of a particular "node" (Person) to determine the max width of a peer line:

     1
    /  \
   2    3
 / | \     \
4  5  6     7 
          /  \
         8    9

So the max of that tree above is 4. Since I am not using a traditional left/right approach AND the number of children can be greater than 2, how would I do this?

Couple things:

  • This is NOT homework
  • The code I have below is generate a max width of roughly 3200 (the max I calculated for the example I have handy is 22)

Here is my code as of now:

private int calculateWidth(def org, int h) {

    def allContacts = Contact.findAllByOrganization(org)
    List<String> headNodes = findHighestNode(org.id, allContacts )

    Contact contact = Contact.get(Long.parseLong(headNodes.get(0)))
    Person parent = new Person(contact.id, contact.fullName)

    int maxWidth = 0;
    int width;
    int heightOfChart = h;
    int i;

    for(i = 1; i <= heightOfChart; i++)
    {
      width = getWidth(parent, i);

      if(width > maxWidth)
        maxWidth = width;
    }

    System.out.println("The max width is = " + maxWidth)
    return ((NODE_HEIGHT + NODE_OFFSET) * (maxWidth))
}

private int getWidth(Person parent, int level)
{

  List<Person> allChildren = getChildren(parent)

  if(allChildren.size() == 0)
    return 0;

  if(level == 1)
    return 1;

  else if (level > 1) {
    int count = 0
    for(Person child : allChildren) {
        count = count + getWidth(parent, level-1)
    }
    return count
  }
}
like image 658
user82302124 Avatar asked Dec 05 '25 09:12

user82302124


2 Answers

I have not really inspected your code but, I would use a breadth first search approach.

some psuedo code:

start with list containing just the trees root. call it CurrNodes.
maxWidth = 1;
start with empty list. call it NextNodes.
while(CurrNodes is not empty) {
   get all children of nodes in CurrNodes and add them to NextNodes
   if number of children is > maxWidth, # of children is the new maxWidth
   CurrNodes = NextNodes
   NextNodes = empty.
}
like image 147
Colin D Avatar answered Dec 08 '25 00:12

Colin D


A way to solve the problem is using a counter array with the length of the tree height, then for each level you seek you can add the counter of the nodes in the array, in the end you just need to get the index with max value in the array. Modifying your code, it could be something like this:

private int calculateWidth(def org, int h) {
    def allContacts = Contact.findAllByOrganization(org);
    List<String> headNodes = findHighestNode(org.id, allContacts );
    Contact contact = Contact.get(Long.parseLong(headNodes.get(0)));
    Person parent = new Person(contact.id, contact.fullName)
    int maxWidth = 0;
    int heightOfChart = h;
    int i;
    //create the counter array, initialized with 0 values by default
    int[] levelWidth = new int[h];
    if (parent != null) {
        levelWidth[0] = 1;
        //I suppose that your "parent" var is the root of your tree.
        fillWidth(parent, 1, levelWidth);
    }
    for(int width : levelWidth) {
        maxWidth = Math.max(maxWidth, width);
    }
    return maxWidth;
}

private void fillWidth(Person parent, int level, int[] levelWidth) {
    List<Person> allChildren = getChildren(parent);
    if (allChildren != null && !allChildren.isEmptty())
        levelWidth[level] += allChildren.size();
        for(Person child : allChildren) {
            fillWidth(parent, level + 1, levelWidth)
        }
    }
}
like image 36
Luiggi Mendoza Avatar answered Dec 07 '25 23:12

Luiggi Mendoza



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!