计算二叉搜索树中的节点

时间:2012-12-07 03:49:03

标签: java recursion binary-search-tree

我需要创建一个递归方法,该方法将二叉搜索树的根节点作为参数。然后,这个递归方法将返回整个二叉搜索树中节点总数的int值。

这是我到目前为止所做的:

public class BinarySearchTree<E> extends AbstractSet<E>
{
protected Entry<E> root; 


//called by the main method
public int nodes()
{
    return nodes(root);
}       

//nodes() will count and return the nodes in the binary search tree

private int nodes(Entry<E> current)
{    
    if(current.element != null)
    { 
        if(current.left == null && current.right == null)
        {
            if(current.element == root.element)
            return 1;                   

            deleteEntry(current);              
            return 1 + nodes(current.parent);
        }
        else if(current.left != null && current.right == null)        
            return nodes(current.left);

        else if(current.left == null && current.right != null)
            return nodes(current.right);

        else if(current.left != null && current.right != null)
            return nodes(current.left) + nodes(current.right);      
    } else return 1;
    return 0;
}

main方法调用节点如下:

        System.out.println ("\nThis section finds the number of nodes "
             + "in the tree"); 

        System.out.println ("The BST has " + bst.nodes() + " nodes");

所以我按顺序运行搜索,一旦我到达没有孩子的节点,我会删除当前节点并返回到父节点并继续。我对上面的方法进行了调试,当程序最终计算并删除根节点左侧和右侧的所有节点并尝试返回1时,程序崩溃并使用NullPointerException()。

这是我的实验室,方法必须是递归的。

我现在很迷茫,有谁知道我做错了什么?

5 个答案:

答案 0 :(得分:15)

你这样做太复杂了。面向对象编程的基本思想是,您可以信任对象来完成他们知道答案的工作。所以,如果我是父母,我可以自己计算,我让我的孩子自己计算,等等。

private int nodes(Entry<E> current) {   
  // if it's null, it doesn't exist, return 0 
  if (current == null) return 0;
  // count myself + my left child + my right child
  return 1 + nodes(current.left) + nodes(current.right);
}

答案 1 :(得分:4)

您有几个问题:

  • 您在计算节点时是否删除了节点? nodes()应该清除树吗?
  • 您将root==nullroot!=null&left==null&&right==nullroot!=null&left!=null&right==null等视为单独案件。他们不是。您有三种情况,并非完全排他性:
    • 如果当前节点不为null,则向计数添加一个。 (这应该总是这样。唯一可能是假的情况是当前节点== root,我们可以事先检测并回避它。)
    • 如果当前节点有一个左子节点,请添加左子节点数。
    • 如果当前节点有正确的孩子,请添加正确的孩子的计数。
  • 出于某种不正当的原因,你正在遍历 up 树。看起来它与删除节点有关...?

但我认为最重要的是,你没有给Entry提供足够的自主权。 :P

节点可以统计自己的孩子。相信它。

class Entry<E> {
    ...

    int count() {
        int result = 1;
        if (left != null) result += left.count();
        if (right != null) result += right.count();
        return result;
    }
}

public int nodes() {
    return (root == null) ? 0 : root.count();
}

如果您的老师不称职,并且坚持在节点外部的某些节点计数功能,您可以执行与尝试相同的操作:

private int nodes(Entry<E> current) {
     int result = 1;
     if (current.left) result += nodes(current.left);
     if (current.right) result += nodes(current.right);
     return result;
}

public int nodes() {
     return (root == null) ? 0 : nodes(root);
}

但在我看来,那个老师应该被解雇。 Entry类是真正的树; BinarySearchTree实际上只是一个引用根的容器。

另外请注意,我对parent s不感兴趣。如果我们从根开始计数,并且每个节点计算其子节点,计算其子节点等等......那么将考虑所有节点。

答案 2 :(得分:0)

删除current中的deleteEntry(current);后,您使用current.parent中的return 1 + nodes(current.parent);

可能是这是抛出NullPointerException的原因..

答案 3 :(得分:0)

嘿,我为二叉树实现了非常干净的计数:

SELECT InstituteId, COUNT(*)
FROM ptable
GROUP BY InstituteId

也许这有助于您了解如何为具有计数的简单二叉树实现类。

此实现通过树中相应节点中的计数来访问计数。

如果您不熟悉.NET 4.6的标记

,请立即告诉我

答案 4 :(得分:0)

public int countNodes(Node root){
    // empty trees always have zero nodes
    if( root == null ){
        return 0;
    }

    // a node with no leafes has exactly one node
    // note from editor: this pice of code is a micro optimization
    // and not necessary for the function to work correctly!
    if( root.left == null && root.right == null ){
        return 1;
    }

    // all other nodes count the nodes from their left and right subtree
    // as well as themselves
    return countNodes( root.left ) + countNodes( root.right ) + 1;
}
相关问题