微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

树节点的高度和层级顺序

如何解决树节点的高度和层级顺序

请查看代码,让我知道问题出在哪里。因为我想找到高度和水平顺序,但输出什么都没有。由于左右节点总是包含空值。

这里是主要功能

  public static void main(String[] args) 
{
        
       Tree t1 = new Tree();
       Tree t2 = new Tree();
       t1.makeTree();
       t1.levelOrder(); //0 1 2 3 4 5 6 13 14 15 7 8 9 10 11 12
       System.out.println("height: " + t1.height()); //3
       t2.makeTree2();
       t2.levelOrder(); //0 1 2 3
       System.out.println("height: " + t2.height()); //1
       System.out.println("sub tree t1 and t1 " + t1.isSubTree(t1));
       System.out.println("sub tree t1 and t2 " + t1.isSubTree(t2)); //t2 is not a subTree of t1
       Tree t3 = new Tree();
       t3.makeTree3();
       t3.levelOrder();
       System.out.println("sub tree t1 and t3 " + t1.isSubTree(t3)); //t3 is a subTree of t1
       Tree t4 = new Tree();
       t4.makeTree4();
       t4.levelOrder();
       System.out.println("sub tree t1 and t4 " + t1.isSubTree(t4)); //t4 is a subTree of t1
 
     }
 }

这里是树类:

class Tree{   
   private static class TNode{
       private int value;
       private TNode parent;
       private TNode left,right;
       private List<TNode> children;
       
       public TNode(){
          this(0,null);
       }
       public TNode(int e){
          this(e,null);
       }
       public TNode(int e,TNode p){
          value = e;
          parent = p;
          left=right=null;
          children = new ArrayList<TNode>();
       }    
   }

   private TNode root;    
   private int size;    

   Tree(){
     root = null;
     size = 0; 
   }

   public TNode createNode(int e,TNode p){
        return new TNode(e,p);
   }

   public TNode addChild(TNode n,int e){
        TNode temp = createNode(e,n);
        n.children.add(temp);
        size++;
        return temp;
   }

   public void makeTree(){
        root = createNode(0,null);
        size++;
        buildTree(root,3);
   }

   public void makeTree2(){
        root = createNode(0,null); 
        size++; 
        buildTree(root,1);
   }

   public void makeTree3(){
        root = createNode(3,null); 
        size++; 
   }

   public void makeTree4(){
        root = createNode(2,null); 
        size += 13; 
        buildTree(root,1);
        size -= 12;
   }

   private void buildTree(TNode n,int i){
        if (i <= 0) return;
        TNode fc = addChild(n,size);
        TNode sc = addChild(n,size);
        TNode tc = addChild(n,size);
        buildTree(fc,i - 1);
        buildTree(sc,i - 2);
        if (i % 2 == 0)
           buildTree(tc,i - 1);    
   } 

   public long height(TNode n){
       /*implement*/
       if (n == null)
            return 0;
         else
         {
             /* compute  height of each subtree */
             long lheight = height(n.left);
             long rheight = height(n.right);
              
             /* use the larger one */
             if (lheight > rheight)
                 return(lheight+1);
             else return(rheight+1);
         }
     // return 0;    }    public long height(){
       return height(root);    
   } 

   public void levelOrder(){
       /*implement*/
        Queue<TNode> queue = new LinkedList<TNode>();
         queue.add(root);
         while (!queue.isEmpty())
         {
  
             
             TNode tempNode = queue.poll();
             //System.out.print(tempNode.value + " ");
  
             /*Enqueue left child */
             if (tempNode.left != null) {
                 queue.add(tempNode.left);
             }
  
             /*Enqueue right child */
             if (tempNode.right != null) {
                 queue.add(tempNode.right);
             }
         }    }    public boolean isSubTree(Tree st){
       /*implement for extra credit*/ return false;    
   } 
}

解决方法

有了 this extra bit of information,问题现在可以回答了:

原始类只有以下数据成员:private int value; private TNode parent; private List<TNode> children;

因此,您正在尝试为任意树实现 height()levelOrder()。您已经知道如何为二叉树实现这些函数。我们需要做的是根据您拥有的数据结构调整您已知的算法。

让我们从您拥有的左/右版本开始:

public long height(TNode n){
  if (n == null) {
    return 0;
  } else {
    /* compute height of each subtree */
    long lheight = height(n.left);
    long rheight = height(n.right);
    
    /* use the larger one */
    if (lheight > rheight) {
      return(lheight+1);
    } else {
      return(rheight+1);
    }
  }
  return 0; 
} 

这是正确的。所需要做的就是将其从左右递归更改为使用子项的内容。算法是一样的,如评论所示:

public long height(TNode n){
  if (n == null) {
    return 0;
  } else {
    /* compute height of each subtree */
    
    /* use the larger one */

  }
  return 0;    
} 

我们如何计算每个子树的高度?

for (TNode child : n.children) {
  /* compute height of each subtree */
  long childHeight = height(child);
}

但我们需要跟踪最大的那个。

long highest = 0;
for (TNode child : n.children) {

  /* compute height of each subtree */
  long childHeight = height(child);

  /* use the larger one */
  highest = Math.max(highest,childHeight);
}
return highest + 1;

综合起来:

public long height(TNode n){
  if (n == null) {
    return 0;
  } else {
    long highest = 0;
    for (TNode child : n.children) {

      /* compute height of each subtree */
      long childHeight = height(child);

      /* use the larger one */
      highest = Math.max(highest,childHeight);
    }
    return highest + 1;
  }
  return 0;    
} 

至于 levelOrder,您可以在那里遵循相同的逻辑。我把它留给你作为练习。


解决此评论:

请指导我如何从非二叉树中找到子树?

由于这是一棵任意树,而不是 BST,我们对子节点的顺序一无所知,因此我们无法寻找特定值。因此,要找到子树,我们必须检查每个子树。

/**
* haystack represents the tree we're looking inside
* needle is the tree we're looking for
*/
private boolean isSubTree(TNode haystack,TNode needle) {
  if (haystack == null && needle == null) {
    // Leaf
    return true;
  }
  if (haystack == null || needle == null) {
    // One is null,the other isn't
    return false;
  }
  if (haystack.value != needle.value) {
    // No match
    return false;
  }

  // We'll assume that order matters,and that all children need to match.
  if (haystack.children.size() != needle.children.size()) {
    return false;
  }

  // Iterate over all children and see if they match
  boolean result = true;
  for (int index = 0; index < haystack.children.size(); index++) {
    result = result && isSubTree(
      haystack.children.get(index),needle.children.get(index));
  }  
  return result;
}

要调用它,请遍历 this.root 中的所有节点(可能使用 levelOrder)并调用上述方法,如果任何调用返回 true,则返回 true。这是一个 O(n*m) 算法,其中 n 是大海捞针中的节点数,m 是针中的节点数。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。