我正在试图弄清楚如何计算树的最大宽度。我没有使用典型的叶/节点结构,而是基于数据库中的数据。我将找到特定“节点”(Person)的所有子节点来确定对等线的最大宽度:
1
/ \
2 3
/ | \ \
4 5 6 7
/ \
8 9
所以上面那棵树的最大值是4.由于我没有使用传统的左/右方法而且孩子的数量可能大于2,我该怎么做?
夫妻俩:
以下是我的代码:
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
}
}
答案 0 :(得分:4)
我没有真正检查过您的代码,但我会使用广度优先搜索方法。
一些伪代码:
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.
}
答案 1 :(得分:1)
解决问题的方法是使用具有树高的长度的计数器数组,然后对于您寻找的每个级别,您可以添加数组中节点的计数器,最后您只需要获取索引具有数组中的最大值。修改你的代码,它可能是这样的:
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)
}
}
}