3

我试图弄清楚如何计算树的最大宽度。我没有使用典型的叶/节点结构,而是基于数据库中的数据。我将找到特定“节点”(Person)的所有子节点来确定对等线的最大宽度:

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

所以上面那棵树的最大值是 4。由于我没有使用传统的左/右方法,并且孩子的数量可能大于 2,我该怎么做?

几件事:

  • 这不是作业
  • 我下面的代码是生成大约 3200 的最大宽度(我为我方便的示例计算的最大值是 22)

这是我现在的代码:

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
  }
}
4

2 回答 2

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.
}
于 2012-08-14T14:20:50.530 回答
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)
        }
    }
}
于 2012-08-14T15:13:37.083 回答