0

I need a class Person to describe persons. Each person has a name and an array consisting of Person-objects, which represent the person's children. The person class has a method getNumberOfDescendants, which returns an integer equal to the total number of descendants of the person, i.e. his children plus grandchildren plus their children etc. Is there a simple way to do this using recursion?

What if you want to count the descendants in a certain generation only? In other words, getNumberOfDescendants(int generation) would return the number of children if generation=1, number of grandchildren if generation=2 etc.

4
  • 3
    This SMELLS like something that should be tagged "homework". Commented Nov 30, 2009 at 19:36
  • 1
    there used to be a "smells-like-homework" tag for that.. Commented Nov 30, 2009 at 19:38
  • No, no, it's nothing to do with course exercise :D Anyway, I wonder, what the exact difference is between "iteration" and "recursion"? I think it's recursion, when you call a method inside itself, like in the sample solutions, but iteration is "for, while" etc.? I guess there is no purely recursive solution? That is, a solution, which does not use the for-loop? Commented Nov 30, 2009 at 20:02
  • Many solutions that are termed recursive have some element of iteration; for example, think about the algorithms to traverse a binary tree -- typically the recursive function calls itself on the left node and then on the right node; this is, in a sense, an iteration of the list of (two) nodes. Recursion is a useful way to get information from a lower level to an upper level, but to get information across a given level (e.g. summarize all of the children of the current node) you'll want to iterate. Commented Nov 30, 2009 at 20:37

4 Answers 4

4

Sure.

public class Person {

private Person[] myChildren;

public int getNumberOfDescendants() {
  if (myChildren == null || myChildren.length==0) return 0;
  int myDescendants = 0;
  for (Person child:myChildren) {
    myDescendants += 1; // for this particular child itself
    myDescendants += child.getNumberOfDescendants();  //add the child's children, grandchildren, etc.
  }
  return myDescendants;
}

}
Sign up to request clarification or add additional context in comments.

3 Comments

Note that the two lines that do the incrementing could easily be replaced with a single line "myChildren += 1 + child.getNumberOfDescendants();". I did it as two lines for clarity and ease of commenting.
Yes, that's the way I finally wrote it. Anyway, thanks for example, now I got the hang of recursion in this.
Fixed a small problem (hadn't specified the return type). Compiles now.
4
getNumberOfDescendants()
{
  int sum = 0;
  for (int n=0; n < descendants.length; n++)
  {
    sum += 1 + descendants[n].getNumberOfDescendants();
  }
  return sum;
}

Note that the "1 +" is the only place where we're actually increasing the count. That line gets called once for every descendant in the tree.

5 Comments

Only problem here is the assumption the descendants array will never be null.
True... I guess I was thinking in terms of collections where even an empty one will still usually have an object allocated that you can traverse (0 times). Does Java allow 0-length arrays?
Yes, the array can exist but have a zero length, in which case your code will work.
If the descendants array is null, it's .length will be 0, and the loop won't be entered.
D'Nabre: No, if the array is initialized but has no members, it's .length will be 0, but if it's null, calling .length on it will cause a null pointer exception.
0

It's not really recursion, per se, but an instance of the class could sum the results of calling the getNumberOfDescendants() method for each of its children.

Alternatively, you could make this method faster by having each instance notify its parent whenever it got a new descendant (either a new child or from being notified by a child). That way, its count of the number of descendants would always be up-to-date.

Comments

0
  public int getNumberDescendents()
  {
    int nDesc = 0;
    if (descendants != null)
    {
      for (Person p : descendants)
      {
        nDesc++; // this child
        nDesc += p.getNumberDescendents(); // this child's desc
      }
    }
    return nDesc;
  }

By the time I wrote the example up, others had posted basically the same thing, so I am kind of redundantly posting.

1 Comment

If you put 4 spaces at the beginning of each line, it will put the code in a nice formatted code block.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.