Counting the nodes in a binary search tree

核能气质少年 提交于 2019-12-06 07:43:50

You are making this way too complicated. The basic idea of object oriented programming is that you trust objects to do the jobs they know the answers to. So if I'm a parent, I can count myself, and I let my children count themselves, and so forth.

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

You have several issues:

  • You're deleting nodes as you count them? Is nodes() supposed to clear the tree?
  • You're treating root==null, root!=null&left==null&&right==null, root!=null&left!=null&right==null, etc as separate cases. They're not. You have three cases, which are not entirely exclusive:
    • If the current node is not null, add one to the count. (This should always be the case. The only case where it might be false is if the current node == root, and we can detect and sidestep that beforehand.)
    • If the current node has a left child, add the left child's count.
    • If the current node has a right child, add the right child's count.
  • You're traversing back up the tree for some ungodly reason. Looks like it has something to do with deleting nodes...?

But the biggest thing in my opinion is, you're not giving enough autonomy to the Entrys. :P

A node can count its own children. Trust it to.

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

If your teacher is incompetent, and insists on some node-counting function outside a node, you can do the same thing you were trying to do:

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

But that teacher should be fired, in my opinion. The Entry class is the real tree; BinarySearchTree is really just a container for a reference to the root.

Also notice, i don't give a damn about the parents. If we start counting from the root, and each node counts its children, which count their children, etc etc... then all nodes will be accounted for.

After you delete current in: deleteEntry(current);, you use current.parent in return 1 + nodes(current.parent);

May be this's the reason of throwing NullPointerException..

Hey I have a very clean counting implemented for a binary tree:

public class Binary<T> where T: IComparable<T>
{
    private Node _root;

    public int Count => _root.Count;

    public void Insert(T item)
    {
        Node newNode = new Node(item);
        if (_root == null)
            _root = newNode;
        else
        {
            Node prevNode = _root;
            Node treeNode = _root;
            while (treeNode != null)
            {
                prevNode = treeNode;
                treeNode = newNode.Item.CompareTo(treeNode.Item) < 1 ? treeNode.Left : treeNode.Right;
            }
            newNode.Parent = prevNode;
            if (newNode.Item.CompareTo(prevNode.Item) < 1)
                prevNode.Left = newNode;
            else
                prevNode.Right = newNode;
        }
    }

    public class Node
    {
        public T Item;

        public Node Parent;
        public Node Left;
        public Node Right;

        public Node(T item, Node parent = null, Node left = null, Node right = null)
        {
            Item = item;
            Parent = parent;
            Left = left;
            Right = right;
        }

        public int Count
        {
            get
            {
                int count = 1;
                count += Left?.Count ?? 0;
                count += Right?.Count ?? 0;
                return count;
            }
        }
    }
}

Maybe this helps you to understand how to implement a class for a simple binary tree with a count.

This implementation accesses the count through a count in the corresponding node in the tree.

Let me now if you are not familiar with the markup of .NET 4.6

Antoniet Ama Aggrey
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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!