我需要创建一个递归方法,该方法将二叉搜索树的根节点作为参数。然后,这个递归方法将返回整个二叉搜索树中节点总数的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()。
这是我的实验室,方法必须是递归的。
我现在很迷茫,有谁知道我做错了什么?
答案 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==null
,root!=null&left==null&&right==null
,root!=null&left!=null&right==null
等视为单独案件。他们不是。您有三种情况,并非完全排他性:
root
,我们可以事先检测并回避它。)但我认为最重要的是,你没有给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;
}