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:
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
}
}
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.
}
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)
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With