繁体   English   中英

N元树深度和度算法

[英]N-ary tree depth and degree algorithm

我在使用几个算法时遇到了一些问题,这些算法应该返回树的最大程度(节点的最大子节点数)和深度(最长分支的维度)。 看起来有些树结构可以工作,而有些树则不工作。 有人可以告诉我代码是否做错了吗?

我的树结构是

public class Tree<T> {

  public Node<T> root;

  public Tree() {
    root = null;
  }

我的节点结构是:

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

学位算法为:

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

最后,深度算法:

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

插入代码为:

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);
      }
    }
  }
}

不起作用的结构是:

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());
}

这将返回5,但应返回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());
}

这应该返回3但返回2

e1到e7是整数。

两件事情。

首先,您的searchAux函数是错误的。 以下行是无用的,因为它的返回值被忽略:

searchAux(node.getSibling(), key);

此外, while循环允许将子节点分配给错误的父节点。 条件

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

如果您要访问的节点没有子代,则为false,无论其键值如何; 这意味着随后的return node; 即使返回的节点不是您要查找的父节点,也可能会执行指令。

例如,在第二个示例中,就是这样。 这是前三个insert s之后的情况(垂直线=父子级,水平线=同级):

e1
|
e2--e3

到目前为止,一切都很好。 但是,当您调用tree.insert(e3, e4)时,e3已被访问但被忽略; e2会返回它(尝试并遍历您的代码)。 从而:

e1
|
e2--e3
|
e4

顺便说一下,这就是第二棵树的样子:

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

第二:据我所知,第一棵树是正确的,即使您的搜索算法错误。 它的深度是5,而不是6(根节点的深度是零):

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

话虽如此,这是递归深度优先搜索的快速草案:

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);
}

(附带说明, return s后不需要else 。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM