Im trying to make it right now using recursion but Im having a hard time, I think I have a logical error.
please someone help me T_T
Here is my code so far
import java.util.ArrayList;
public class BTNode{
private BTNode root, left,right;
private int item;
public BTNode(int item){
this(item,null,null,null);
}
public BTNode(int item, BTNode left, BTNode right, BTNode root,int count){
this.item = item;
this.left = left;
this.right = right;
this.root = root;
this.count=count;
}
public void build(){
this.left = new BTNode(40);
this.left.root = this;
this.right = new BTNode(100);
this.right.root = this;
this.left.right = new BTNode(45);
this.left.right.root = this.left;
this.left.left = new BTNode(25);
this.left.left.root = this.left;
this.right.left = new BTNode(70);
this.right.left.root = this.right;
this.right.right = new BTNode(200);
this.right.right.root = this.right;
}
public void inorder(){//recursion
//traverse the left
if(left != null)
left.inorder();
//visit the root do the item
System.out.print(this.item+" ");
//traverse the right
if(right != null)
right.inorder();
}
public String inToString(){
return ((left == null)?"": left.inToString()) + item + " " + ((right == null)?"": right.inToString()+" ");
}
//preorder()
public void preorder(){
//visit the root do the item
System.out.print(this.item+" ");
//traverse the left
if(left != null)
left.preorder();
//traverse the right
if(right != null)
right.preorder();
}
//preToString()
public String preToString(){
return item+ " "+((left == null)?"": left.preToString())+ ((right == null)?"": right.preToString()+" ");
}
//postorder()
public void postorder(){
//traverse the left
if(left != null)
left.postorder();
//traverse the right
if(right != null)
right.postorder();
//visit root do the item
System.out.print(this.item+" ");
}
//postToString()
public String postToString(){
return ((left == null)?"": left.postToString()) + ((right == null)?"": right.postToString()+" ")+item+ " ";
}
//findsum-recursive
public int findsum(){
//traverse left,if null traverse to right then add the two item lastly add to the root
return ((left == null)?0: left.findsum()) + ((right == null)?0: right.findsum())+item;
}
//findlevel-recursive
public int findlevel(){
//check left && right if it is not null then iterate method recursively
if (left == null)
return 0;
else if(right == null)
return 0;
else
return 1 + left.findlevel();
}
/*
//ancestor-recursive
public BTNode ancestor(int value){
if(left.count== 2){//check the root
return left.ancestor();//traverse left node
}
System.out.print(item+" ");//print item if the left turns false
if(root != null){
right.ancestor();//traverse right node
}
}*/
public int count(){
//check if left || right are null then return 0, otherwise method were recursively executed
return (((left==null)?0:1+left.count())+((right==null)?0:1+right.count()));
}
public void reference(){
//check left != null print the root, traverse left, traverse right
if(left != null)
left.reference();
if(left != null)
System.out.print(item+" ");
if(right != null)
right.reference();
}
public void sort(){
}
public void insert(int given){
BTNode node = new BTNode(given);
if(item == 0)
root = node;
else
{
BTNode current = root; //points to the current Node
BTNode parent; //points to the parent Node
while(current != null)
{
if(item > given)
{
parent = current;
current = left;
}
if(item < given)
{
parent = current;
current = right;
}
}
current = node;
if(item < given)
right = node;
else
left = node;
}
right.inorder();
}
public boolean contains(int given){
return ((left==null)?false:left.contains(given))|| item==given || ((right == null)?false : right.contains(given));
/*if(left != null)
left.contains(given);
if(right != null)
right.contains(given);
return item == given;*/
}
public static void main(String[]args){
BTNode root = new BTNode(50);
root.build();
System.out.print("\nGiven :"+root.inToString());
System.out.println("\ninorder");
root.inorder();
System.out.println("\npreorder");
root.preorder();
System.out.println("\npostorder");
root.postorder();
System.out.println("\nfindsum");
System.out.println(root.findsum());
System.out.println("\nfindlevel");
//System.out.println(root.findlevel(200));
System.out.println(root.findlevel());
System.out.println("\nancestor");
//System.out.println(root.ancestor());
root.ancestor();
System.out.println("\ncount");
System.out.println(root.count());
System.out.println("\nreference");
//System.out.println(root.reference());
root.reference();
System.out.println("\nsort");
//System.out.print(root.sort());
root.sort();
System.out.println("\nContains");
System.out.println(root.contains(new Integer(70)));
System.out.println("\ninsert");
//System.out.print(root.sort());
root.insert(new Integer(71));
root.printinorder();
}
}
please also check my insertion mechanism... I dont think that is the right way to do it
Since your question is unclear, I am answering both of your potential questions.
1- If you want to find the minimum ancestor of a node, what you can do is given a node keep traversing up its parents while keeping a track of the smallest parent value found so far. Once you reach the root node you will have the smallest value. The time complexity of this algorithm is O(h) where h is the height of the tree. As this is very simple I am not giving a code sample here.
2- If you want to find the LCA (which is what you question title is about) you can do something very similar. If we assume that the keys n1 and n2 are present in Binary Tree, we can find LCA using single traversal of Binary Tree and without extra storage for path arrays. The idea is to traverse the tree starting from root. If any of the given keys (n1 and n2) matches with root, then root is LCA (assuming that both keys are present). If root doesn’t match with any of the keys, we recur for left and right subtree. The node which has one key present in its left subtree and the other key present in right subtree is the LCA. If both keys lie in left subtree, then left subtree has LCA also, otherwise LCA lies in right subtree. Here is an example code that you can tailor according to your need (this code works):
//Java implementation to find lowest common ancestor of
// n1 and n2 using one traversal of binary tree
/* Class containing left and right child of current
node and key value*/
class Node
{
int data;
Node left, right;
public Node(int item)
{
data = item;
left = right = null;
}
}
public class BinaryTree
{
//Root of the Binary Tree
Node root;
Node findLCA(int n1, int n2)
{
return findLCA(root, n1, n2);
}
// This function returns pointer to LCA of two given
// values n1 and n2. This function assumes that n1 and
// n2 are present in Binary Tree
Node findLCA(Node node, int n1, int n2)
{
// Base case
if (node == null)
return null;
// If either n1 or n2 matches with root's key, report
// the presence by returning root (Note that if a key is
// ancestor of other, then the ancestor key becomes LCA
if (node.data == n1 || node.data == n2)
return node;
// Look for keys in left and right subtrees
Node left_lca = findLCA(node.left, n1, n2);
Node right_lca = findLCA(node.right, n1, n2);
// If both of the above calls return Non-NULL, then one key
// is present in once subtree and other is present in other,
// So this node is the LCA
if (left_lca!=null && right_lca!=null)
return node;
// Otherwise check if left subtree or right subtree is LCA
return (left_lca != null) ? left_lca : right_lca;
}
/* Driver program to test above functions */
public static void main(String args[])
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
tree.root.right.left = new Node(6);
tree.root.right.right = new Node(7);
System.out.println("LCA(4, 5) = " +
tree.findLCA(4, 5).data);
System.out.println("LCA(4, 6) = " +
tree.findLCA(4, 6).data);
System.out.println("LCA(3, 4) = " +
tree.findLCA(3, 4).data);
System.out.println("LCA(2, 4) = " +
tree.findLCA(2, 4).data);
}
}
This is method and code are from http://www.geeksforgeeks.org/lowest-common-ancestor-binary-tree-set-1/ on this site you can run the code in IDE as well online.
Related
I was creating a binary tree using linked list in java, which inserts the value according to the height of the tree i.e if the height is even or odd. I wrote a code which initially had no temporary node for insertion of values to the root node and further left or right subtree nodes. But when I displayed this tree, output had no root node as if it was overwritten.
Below is the code of my initial program. Concentrate on public void insert_node() function.
import java.util.Scanner;
public class binary_tree {
private TreeNode root;
private int height = 0;
public static class TreeNode {
private int data;
private TreeNode left;
private TreeNode right;
public TreeNode(int user_input) {
this.data = user_input;
}
}
public void insertNode(TreeNode newnode) { // HERE....I have used only root.
if (root == null) {
root = newnode;
height += 1;
return;
}
if (height % 2 != 0) {
System.out.println(height);
while (root.left != null) {
root = root.left;
}
root.left = newnode;
height += 1;
return;
}
while (root.right != null) {
root = root.right;
}
root.right = newnode;
height += 1;
}
public void display(TreeNode rootnode) {
TreeNode temp = rootnode;
if (temp == null)
System.out.println("Tree Empty !!!");
else {
System.out.println("press 1 for LEFT SUBTREE \npress 2 for RIGHT SUBTREE.");
Scanner sc = new Scanner(System.in);
int ch = sc.nextInt();
while (temp != null) {
System.out.println(temp.data + " $");
if (ch == 1)
temp = temp.left;
else
temp = temp.right;
}
}
System.out.println("Height of the tree = " + height);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
binary_tree bt = new binary_tree();
TreeNode newNode = new TreeNode(50);
bt.insertNode(newNode);
TreeNode newNode2 = new TreeNode(10);
bt.insertNode(newNode2);
TreeNode newNode3 = new TreeNode(100);
bt.insertNode(newNode3);
TreeNode newNode4 = new TreeNode(5);
bt.insertNode(newNode4);
TreeNode newNode5 = new TreeNode(1000);
bt.insertNode(newNode5);
bt.display(bt.root);
}
}
Output
press 1 for LEFT SUBTREE
press 2 for RIGHT SUBTREE.
3
10 $
1000 $
Height of the tree = 5
You can see in the above code, that the 50 $ is missing which was supposed to be the root node.
Now, if I use a temporary node which in my case is current_node then this root node sustains somehow. See in the code below.
import java.util.Scanner;
public class binary_tree {
private TreeNode root;
private int height = 0;
public static class TreeNode {
private int data;
private TreeNode left;
private TreeNode right;
public TreeNode(int user_input) {
this.data = user_input;
}
}
public void insertNode(TreeNode newnode) {
TreeNode current_node = root; //THIS IS THE TEMPORARY NODE
if (current_node == null) {
root = newnode;
height += 1;
return;
}
if (height % 2 != 0) {
System.out.println(height);
while (current_node.left != null) {
current_node = current_node.left;
}
current_node.left = newnode;
height += 1;
return;
}
while (current_node.right != null) {
current_node = current_node.right;
}
current_node.right = newnode;
height += 1;
}
public void display(TreeNode rootnode) {
TreeNode temp = rootnode;
if (temp == null)
System.out.println("Tree Empty !!!");
else {
System.out.println("press 1 for LEFT SUBTREE \npress 2 for RIGHT SUBTREE.");
Scanner sc = new Scanner(System.in);
int ch = sc.nextInt();
while (temp != null) {
System.out.println(temp.data + " $");
if (ch == 1)
temp = temp.left;
else
temp = temp.right;
}
}
System.out.println("Height of the tree = " + height);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
binary_tree bt = new binary_tree();
TreeNode newNode = new TreeNode(50);
bt.insertNode(newNode);
TreeNode newNode2 = new TreeNode(10);
bt.insertNode(newNode2);
TreeNode newNode3 = new TreeNode(100);
bt.insertNode(newNode3);
TreeNode newNode4 = new TreeNode(5);
bt.insertNode(newNode4);
TreeNode newNode5 = new TreeNode(1000);
bt.insertNode(newNode5);
bt.display(bt.root);
}
}
Output
press 1 for LEFT SUBTREE
press 2 for RIGHT SUBTREE.
3
50 $
100 $
1000 $
Height of the tree = 5
So anyone who can tell me what's happening here? What difference does that current_node is making?
Why do we need a temporary node while inserting values in a node in Linked list?
Because you are traversing to the leaves of the tree here:
while (current_node.left != null) {
current_node = current_node.left;
}
current_node.left = newnode;
height += 1;
In these lines of code, you are trying to find the leftmost leaf so as to insert newnode, right? You want to use a variable to keep track of which node you are currently on, and "go left" by doing someVariable = someVariable.left;.
You could use root to keep track of where you are at, but root already has a purpose - to record the root of the tree! If you did root = root.left;, you are making the left node of the original root be the new root! Say your tree was:
50
/ \
10 100
Doing root = root.left deletes most of it:
10
This is problematic because this means your tree essentially "forgets" about a part of the tree. Technically, The 50 and 100 nodes still exists and 50 is still connected to 10, but your binary_tree object doesn't have access to it anymore. The only point of access it has is root, which you have now set to the node 10.
What actually happens in your program is: it correctly inserts 50, 10, and 100, then when adding 5, tries to traverse down the left subtree. This makes the root "10", and adding 5 becomes:
10
/
5
It then adds 1000 correctly:
10
/ \
5 1000
Hence it prints 10 and 1000.
Using a brand new variable solves this problem, because the brand new variable has nothing to do with root.
The BST is as follows:
50 (Root 1)
/ \
40 80 (Root 2)
/ \
20 41
As you can see there are 2 root's that I am dealing with. I have tried the following code which does return the height of the tree from ROOT 1. I don't quite exactly know how to return the height from ROOT 2.
Any help on how to solve would be appreciated.
// Java program to find height of tree
// A binary tree node
class Node
{
int data;
Node left, right;
Node(int item)
{
data = item;
left = right = null;
}
}
class BinaryTree
{
Node root;
int maxDepth(Node node)
{
if (node == null)
return 0;
else
{
/* compute the depth of each subtree */
int lDepth = maxDepth(node.left);
int rDepth = maxDepth(node.right);
/* use the larger one */
if (lDepth > rDepth)
return (lDepth + 1);
else
return (rDepth + 1);
}
}
/* Driver program to test above functions */
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
System.out.println("Height of tree is : " +
tree.maxDepth(tree.root));
}
Your function for finding max depth seems like to work correctly. So fixing this issue is pretty simple.
System.out.println("Height of tree is : " +
tree.maxDepth(tree.root));
The above line prints out the height of the tree starting at the root. But if you were to start at "root 2" as you call it you would need to modify this line to start at the correct node.
System.out.println("Height of tree is : " +
tree.maxDepth(tree.root.right));
Adding an item to a Tree class should be made through a insert method.
And we can make the Node class private, it is used only by BinaryTree class.
A better data structure for a tree should be like the following, which has public insert and height methods.
public class BinaryTree {
private class Node {
private int value;
private Node left;
private Node right;
private Node(int value) {
this.value = value;
}
}
private Node root;
public void insert(int item) {
var node = new Node(item);
if (root == null) {
root = node;
return;
}
var current = root;
while (true) {
if (item < current.value) {
if (current.left == null) {
current.left = node;
break;
}
current = current.left;
} else {
if (current.right == null) {
current.right = node;
break;
}
current = current.right;
}
}
}
public int height() {
return height(root);
}
private int height(Node root) {
if (root == null)
return -1;
if (isLeaf(root))
return 0;
return 1 + Math.max(height(root.left), height(root.right));
}
private boolean isLeaf(Node node) {
return node.left == null && node.right == null;
}
}
And to use it, just add some values, and print the height.
It is way easier to insert an item with this tree class.
BinaryTree tree = new BinaryTree();
tree.insert(50);
tree.insert(40);
tree.insert(80);
tree.insert(20);
tree.insert(41);
System.out.println(tree.height());
I'm working on a binary search tree where i have to delete a node. The node has already been found, so i don't need to traverse and find the specific node. All i need is to delete a node, which is taken as an arguement.
I have started the the node remove method and currently only done how to delete a node if it has no children or is a leaf node. How do i implement a java code which will delete if it has 1 children or a parent?
my current remove method:
public void removeHelper(Node focus){
if(focus.leftChild == null && focus.rightChild == null){
focus = null;
}
// if the node has 1 child
// if the node has 2 children
}
You need to travel down the tree, because you will need to replace the root field, or either the leftChild or rightChild of the parent node.
To remove a node that has both leftChild and rightChild not null, you can replace the node with either the rightmost node of the left subtree, or the leftmost node of the right subtree.
In this example, I assume that the methods are in a class (Tree?) that have a Node field called root, and that the Nodes have a field value that is a Comparable:
public void remove(Node focus) {
root = removeHelper(root, focus);
}
public static Node removeHelper(Node root, Node focus) {
if (root == null) {
return null;
} else if (root == focus) {
if (focus.leftChild == null) {
return focus.rightChild;
} else if (focus.rightChild == null) {
return focus.leftChild;
} else {
Node node = removeLeftMostOfRight(focus);
node.leftChild = focus.leftChild;
node.rightChild = focus.rightChild;
return node;
}
} else {
int r = focus.value.compareTo(root.value);
if (r < 0) {
root.leftChild = removeHelper(root.leftChild, focus);
} else {
root.rightChild = removeHelper(root.rightChild, focus);
}
return root;
}
}
private static Node removeLeftMostOfRight(Node focus) {
Node node = focus.rightChild;
if (node.leftChild == null) {
focus.rightChild = node.rightChild;
} else {
Node prev;
do {
prev = node;
node = node.leftChild;
} while (node.leftChild != null);
prev.leftChild = node.rightChild;
}
return node;
}
Note that in languages like C/C++ you can have pointers to pointer, that allow a much simpler and more efficient implementation of binary trees.
I could not find people to explain me this java code properly so finally I am posting this question.please explain the process how that particular statement is affecting the tree.the problems are stated in the comments.I have problems in the BST class.
import java.util.Scanner;
class BSTNode
{
BSTNode left, right;
int data;
public BSTNode()
{
left = null;
right = null;
data = 0;
}
public BSTNode(int n)
{
left = null;
right = null;
data = n;
}
public void setLeft(BSTNode n)
{
left = n;
}
public void setRight(BSTNode n)
{
right = n;
}
public BSTNode getLeft()
{
return left;
}
public BSTNode getRight()
{
return right;
}
public void setData(int d)
{
data = d;
}
public int getData()
{
return data;
}
}
class BST
{
private BSTNode root;
public BST()
{
root = null;
}
public boolean isEmpty()
{
return root == null;
}
Why is the insert function written like root=insert(...... Is it returning root = actual root element each time?
public void insert(int data)
{
root = insert(root, data);
}
I understand how the inserting process is going on but what is the insert function returning? I know that it returns some node but how the is the process going on during iteration?
private BSTNode insert(BSTNode node, int data)
{
if (node == null)
node = new BSTNode(data);
else
{
if (data <= node.getData())
node.left = insert(node.left, data);
else
node.right = insert(node.right, data);
}
return node;
}
public void delete(int k)
{
if (isEmpty())
System.out.println("Tree Empty");
else if (search(k) == false)
System.out.println("Sorry "+ k +" is not present");
else
{
root = delete(root, k);
Again, why is the delete function written like root=delete(.....? Is it returning root =actual root element each time?
System.out.println(k+ " deleted from the tree");
}
}
private BSTNode delete(BSTNode root, int k)
{
BSTNode p, p2, n;
if (root.getData() == k)
{
BSTNode lt, rt;
lt = root.getLeft();
rt = root.getRight();
if (lt == null && rt == null)
return null;
else if (lt == null)
{
p = rt;
return p;
}
else if (rt == null)
{
p = lt;
return p;
}
else
{
//case when we delete node having both children.
p2 = rt;
p = rt;
//getting the min of the right child subtree in p variable .
while (p.getLeft() != null)
p = p.getLeft();
p.setLeft(lt);
Please explain what is happening here and why is p2 i.e rt being returned.
return p2;
}
}
if (k < root.getData())
{
n = delete(root.getLeft(), k);
root.setLeft(n);
}
else
{
n = delete(root.getRight(), k);
root.setRight(n);
}
return root;
}
public int countNodes()
{
return countNodes(root);
}
In the delete portion of your code, what you are doing is checking to see if the node (called root) has its data value equal to the value you want to delete (k). If that is true, then you examine both children which you seem to grasp. So then we get down to your question when you have both children of the node not null. In this case you want to delete the current node (root) of the subtree you are on, but you need to choose a node (either the left or right) to promote to the position of this node. So (assuming this tree is not balanced) you simply make a choice (left or right) of the subtree to promote to the know root. Keep in mind here that you are only calling the current node root because it is the root of some subtree within the larger tree (this does not mean the actual root of the tree unless that is the value that was passed in as root). Knowing that all of the values in the right child subtree are going to be greater than those in the left child subtree, you simply take the current node's left subtree then recurse as far down the left children of the right subtree as you can go until you're to the end. You then set this node's left child to the entire left subtree.
//case when we delete node having both children.
p2 = rt;
p = rt;
//getting the min of the right child subtree in p variable .
while (p.getLeft() != null)
p = p.getLeft();
p.setLeft(lt);
Notice in the statement
p = rt;
You are setting P to be the root of the of the right subtree. Then p is now the right child of the current root passed in.
while (p.getLeft() != null)
p = p.getLeft();
p.setLeft(lt);
This is basically saying that for that right subtree, If the root node has a left child then set p to that and keep doing so until that value is null. This will keep going down the left children of that right subtree. Finally once that value is null
p.setLeft(lt);
Will set the left child of that left most leaf in the right subtree to the entire left subtree that you started with. And return the node that you said was the right subtree of the original (now with the left subtree of the original appended to its leftmost leaf).
I need to create a recursive method that takes as a parameter the root node of a binary search tree. This recursive method will then return the int value of the total number of nodes in the entire binary search tree.
This is what I have so far:
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;
}
The main method calls nodes like so:
System.out.println ("\nThis section finds the number of nodes "
+ "in the tree");
System.out.println ("The BST has " + bst.nodes() + " nodes");
So I was running the search by traveling in order, once I'd get to a node with no children I would delete the current node and return to the parent node and continue. I ran a debug of the method I have above and the program crashes with a NullPointerException() when it finally counts and removes all the nodes on the left and right side of the root node and tries to return 1.
This is for my lab, the method MUST be recursive.
I'm very lost at this point, does anyone know what I'm doing wrong?
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.
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;
}
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