4

I'm having some problems with a couple algorithms that should return the maximum degree (the max number of children of a node) and depth (dimension of the longest branch) of a tree. It looks like with some Tree structures they work, with some others they don't. Can someone please tell me if I'm doing something wrong with the code?

My Tree structure is

public class Tree<T> {

  public Node<T> root;

  public Tree() {
    root = null;
  }

My Node structure is:

public class Node<T>{
  public T elem; 
  private Node<T> father;
  private Node<T> child; 
  private Node<T> sibling;
  private T epsilon;

public Node(T elem){   
  this.elem = elem;
  this.father = null;
  this.child = null;
  this.sibling = null;  
}

The degree algorithm is:

public int degree(){
int breadth = 0;
int max = 0;
return auxDegree(this.root, breadth, max);
}

public int auxDegree(Node<T> node, int count, int maxChild){
if(node!=null){
  if(node.getChild()!=null){ 
    maxChild = Math.max(auxDegree(node.getChild(), 0, maxChild), auxDegree(node.getSibling(), 0, maxChild));
    count = countSibling(node.getChild()) + 1;
    return (count>maxChild) ? count : maxChild;
  }else return maxChild;
 }else return maxChild;
}

Finally, the depth algorithm:

public int depth(){
  int deepness = 0;
  return auxDepth(this.root, deepness);
}

public int auxDepth(Node<T> node, int maxDepth){
  if(node!=null){
    if(node.getChild()!=null){
       maxDepth = Math.max(maxDepth, auxDepth(node.getChild(), maxDepth));
       maxDepth = maxDepth + 1;
       return maxDepth;
    }else{
      return maxDepth;
    }
  }else return maxDepth;
}

The Insert code is:

public Node<T> search(T key){
  return searchAux(this.root, key);
}

private Node<T> searchAux(Node<T> node, T key){
  if(node == null) 
    return null;
  else{
    while(node.getChild() != null && key != node.getElem()){
      node = node.getChild();
      searchAux(node.getSibling(), key); 
    }
  }  
   return node;  
}

public void insert(T father_key, T child_key){
  if(IsEmpty())
    this.root = new Node<T>(child_key);
  else{
    Node<T> node = new Node<T>(child_key);
    Node<T> father = search(father_key);
    if(father.getChild() == null){
      father.setChild(node);
      node.setParent(father);
     }else{
     if (father.getChild() != null){
       Node<T> brother = father.getChild(); 
       while(brother.getSibling() != null){
         brother = brother.getSibling(); 
       }
       brother.setSibling(node);
       node.setParent(father);
      }
    }
  }
}

The structure that are not working are:

public void Test_Depth(){
  tree.insert(null, e2);
  tree.insert(e2, e3);
  tree.insert(e2, e1);
  tree.insert(e3, e4);
  tree.insert(e4, e5);
  tree.insert(e5, e6);
  tree.insert(e6, e7);
  assertEquals(6,tree.depth());
}

This returns 5 but should return 6

public void Test_Depth(){
  tree.insert(null, e1);
  tree.insert(e1, e2);
  tree.insert(e1, e3);
  tree.insert(e3, e4);
  tree.insert(e3, e5);
  tree.insert(e3, e6);
  assertEquals(3,tree.degree());
}

This should return 3 but returns 2

e1 to e7 are integers.

Leo
  • 161
  • 1
  • 2
  • 11

1 Answers1

1

Two things.

First and foremost, your searchAux function is wrong. The following line is useless, because its return value is ignored:

searchAux(node.getSibling(), key);

Moreover, the while loop allows for children nodes to be assigned to wrong parents. The condition

node.getChild() != null && key != node.getElem()

is false if the node you're visiting has no children, regardless of its key value; this means that the ensuing return node; instruction might be executed even if the node you are returning is not the parent node you are looking for.

This is what happens, for instance, in your second example. This is the situation after the first three inserts (vertical line = parent-child, horizontal line = sibling):

e1
|
e2--e3

So far so good. When you call tree.insert(e3, e4), though, e3 is visited but ignored; e2 is returned in its stead (try and walk through your code). Thus:

e1
|
e2--e3
|
e4

This is what the second tree looks like in the end, by the way:

e1
|
e2--e3
|
e4
|
e5
|
e6

Second: the first tree is correct, as far as I can tell, even though your search algorithm is wrong. Its depth is 5, not 6 (depth of root node is zero):

0: e2
   |
1: e3--e1
   |
2: e4
   |
3: e5
   |
4: e6
   |
5: e7

That being said, here's a quick draft for a recursive depth-first search:

private Node<T> searchAux(Node<T> node, T key){
    if(node == null) 
        return null;
    if (node.getElem() == key)
        return node;
    if (node.getChild() != null) {
        Node<T> foundNode = searchAux(node.getChild(), key);
        if (foundNode != null)
            return foundNode;
    } 
    return searchAux(node.getSibling(), key);
}

(On a side note, you don't need elses after returns.)

themiurge
  • 1,439
  • 15
  • 20
  • Ok. Now Insert should work. I verifyed with various Trees. Still, Depth and Degree methods aren't working. – Leo May 12 '17 at 11:40
  • 1
    At a first glance, the `auxDepth` methods never visits siblings. Try to fix that. – themiurge May 12 '17 at 11:58
  • I changed the two methods using a while to visit all siblings and it's working. Thanks a lot for the help! – Leo May 12 '17 at 16:45