Remove Subtree with specific value - java

The problem I'm trying to solve is that given a binary tree, remove subtree which has the same value as the parameter value passed. Here's my code but I don't believe it works as the altered tree is the exact same as the original tree.
Before:
5
/ \
3 2
/ \ / \
2 1 4 3
After removal of subtree of value 2:
5
/
3
\
1
public TreeNode removeSubtree(TreeNode root, int value){
TreeNode copy = root;
removeSubtreeRecursion(copy, value);
return root;
}
public void removeSubtreeRecursion(TreeNode root, int val){
if(root == null) return;
else if(root.val == val) root = null;
else{
removeSubtreeRecursion(root.left, val);
removeSubtreeRecursion(root.right, val);
}
}

You can use parent node instead of current node to be able to modify it. It could be something like this:
public TreeNode removeSubtree(TreeNode root, int value){
if (root != null && root.val == value) return null;
removeSubtreeRecursion(root, value);
return root;
}
public void removeSubtreeRecursion(TreeNode parent, int val) {
if (parent.left != null && parent.left.val == val) parent.left = null;
else removeSubtreeRecursion(parent.left, val);
if (parent.right != null && parent.right.val == val) parent.right = null;
else removeSubtreeRecursion(parent.right, val);
}
In your implementation root = null modifies local reference. You can read more about this in Pass by reference in Java.

Related

Java pointer or node assignment understanding wrong?

A problem I'm solving is asking to insert a node inside a binary search tree, then return the root of the entire binary tree at the end.
The issue I seem to be having is saving the inserted node inside the original tree given it's root. My code is below:
static Node Insert(Node root,int value) {
insertAux(root, value);
return root;
}
static void insertAux(Node root, int value) {
if (root == null) {
root = new Node();
root.data = value;
root.left = root.right = null;
} else {
if (value > root.data) {
insertAux(root.right, value);
} else {
insertAux(root.left, value);
}
}
}
When I test this with the following tree:
4
/ \
2 7
/ \
1 3
it should result in:
4
/ \
2 7
/ \ /
1 3 6
I have tested this and my insertAux function does in fact assign root to a new Node() and the data for that node to the value 6 when it hits the null case at the end of the function. I have also tested and made sure that my Insert function returns the original root at the end of the entire call. However when I try to see if insertAux has assigned root.right.left to a new Node() and its data to 6 inside of the Insert function, I get a null pointer exception where root.right.left is null. Why is this, is my understanding of pointers or node assignment for Java wrong?
static Node insertAux(Node root, int value) {
if (root == null) {
root = new Node();
root.data = value;
root.left = root.right = null;
} else {
if (value > root.data) {
root.right = insertAux(root.right, value);
} else {
root.left = insertAux(root.left, value);
}
}
return root;
}
Your insertAux() method should be like this.
First of all it should have a return type as Node.
What your doing wrong here is that you are not creating a link between the parent node and child node. So in your case, a new Node with data 6 is created but it is actually never assigned to its parent.
So you need to assign the newly created node by returning it and assigning it to parent.In your method here
if (value > root.data) {
root.right = insertAux(root.right, value);
} else {
root.left = insertAux(root.left, value);
}
Java pass parameters by value (i.e not by reference), internal assignment to root is lost after return from function. Try return in different way, maybe
static Node insertAux(Node root, int value) {

Finding Inorder Successor in Binary Search Tree [duplicate]

This question already has answers here:
In Order Successor in Binary Search Tree
(19 answers)
Closed 5 years ago.
I'm creating Binary Search Tree class I got all my functions working accept the Successor.
My tree input is
30 10 45 38 20 50 25 33 8 12
When I print Inorder traversal it come up as
8 10 12 20 25 30 33 38 45 50
When I enter value 8 its says its successor is 12. Same for input 10 and 12 itself.
When I enter value 33 it says successor is 50. Which its not.
I can't seem to fix it. Any help of suggestion will be appreciated.
I'm calling it in main like:
BinarySearchTree BST = new BinarySearchTree(array);
BST.getSeccessor(a); // where a is user input to find it successor
Following is my code...
public TreeNode Successor(TreeNode node) {
if (node == null)
return node;
if (node.right != null) {
return leftMostNode(node.right);
}
TreeNode y = node.parent;
while (null != y && (y.right).equals(node)) {
node = y;
y = y.parent;
}
return y;
}
public static TreeNode leftMostNode(TreeNode node) {
if (null == node) { return null; }
while (null != node.left) {
node = node.left;
}
return node;
}
/** Search value in Tree need for Successor **/
public TreeNode Search(int key) {
TreeNode node = root;
while (node != null) {
if (key < node.value) {
node = node.left;
} else if (key > node.value) {
node = node.right;
}
return node;
}
return null;
}
/** Returns Successor of given value **/
public int getSuccessor(int val) {
TreeNode node = Successor(Search(val));
return node.value;
}
I added working solution based on pseudo-code in Niklas answer :
public TreeNode successor(TreeNode node) {
if (node == null)
return node;
if (node.right != null) {
return leftMostNode(node.right);
}
while (null != node.parent /*while we are not root*/
&& node.parent.right == node) /* and while we are "right" node */ {
node = node.parent; // go one level up
}
return node.parent;
}
For this to work, you have to fix implementation of some of your methods (provided below) :
/** Search value in Tree need for Successor **/
public TreeNode search(int key) {
TreeNode node = root;
while (node != null
&& key != node.value) {
if(key < node.value) {
node = node.left;
} else if (key > node.value) {
node = node.right;
}
}
return node;
}
/** Returns Successor of given value **/
public int getSuccessor(int val) {
TreeNode node;
if (null == (node = search(val))
|| (null == (node = successor(node))) {
// either val is not in BST, or it is the last value-> no successor
return ERROR_CODE; // -1, for instance;
}
return node.value;
}
A possible algorithm would be the following:
If you have a non-empty right subtree, the successor is the smallest value in that subtree
Otherwise, walk up the tree unless you are no longer the right child of your parent or until you reach the root
If you are at the root now, you have no successor. Otherwise, walk up one more step and you are at the successor
Example:
if node.right != null
return leftmostInSubtree(node.right)
while node != root && node.parent.right == node
node = node.parent
if node == root
return null
return node.parent
The inorder successor is going to be
if (node.hasRight())
node = node.getRight();
else {
while (node.isRightChild())
node = node.getParent();
return node.getParent();
}
while (node.hasLeft())
node = node.getLeft();
return node;
Might be a good idea to put some null checks in there, too.
I think the above code won't work for the rightmost last node.
Here is the improved version:
if(node.right!=null)
{
node=node.right;
while(node.left!=null)
node=node.left;
}`
else if(node.parent==root)
return null;
else if(node==node.parent.left)
node=node.parent;
else
{
while(node.parent!=null)
node=node.parent
}
return node;

Recursive Binary Search Tree Insert

So this is my first java program, but I've done c++ for a few years. I wrote what I think should work, but in fact it does not. So I had a stipulation of having to write a method for this call:
tree.insertNode(value);
where value is an int.
I wanted to write it recursively, for obvious reasons, so I had to do a work around:
public void insertNode(int key) {
Node temp = new Node(key);
if(root == null) root = temp;
else insertNode(temp);
}
public void insertNode(Node temp) {
if(root == null)
root = temp;
else if(temp.getKey() <= root.getKey())
insertNode(root.getLeft());
else insertNode(root.getRight());
}
Thanks for any advice.
// In java it is little trickier as objects are passed by copy.
// PF my answer below.
// public calling method
public void insertNode(int key) {
root = insertNode(root, new Node(key));
}
// private recursive call
private Node insertNode(Node currentParent, Node newNode) {
if (currentParent == null) {
return newNode;
} else if (newNode.key > currentParent.key) {
currentParent.right = insertNode(currentParent.right, newNode);
} else if (newNode.key < currentParent.key) {
currentParent.left = insertNode(currentParent.left, newNode);
}
return currentParent;
}
Sameer Sukumaran
The code looks a little confusing with overloaded functions. Assuming member variables 'left' and 'right' to be the left child and right child of the BSTree respectively, you can try implementing it in the following way:
public void insert(Node node, int value) {
if (value < node.value)
{
if (node.left != null)
{
insert(node.left, value);
}
else
{
node.left = new Node(value);
}
}
else if (value > node.value)
{
if (node.right != null)
{
insert(node.right, value);
}
else
{
node.right = new Node(value);
}
}
}
........
public static void main(String [] args)
{
BSTree bt = new BSTree();
Node root = new Node(100);
bt.insert(root, 50);
bt.insert(root, 150);
}
You should have a look to this article. It helps to implement a tree structure and search, insert methods:
http://quiz.geeksforgeeks.org/binary-search-tree-set-1-search-and-insertion/
// This method mainly calls insertRec()
void insert(int key) {
root = insertRec(root, key);
}
/* A recursive function to insert a new key in BST */
Node insertRec(Node root, int key) {
/* If the tree is empty, return a new node */
if (root == null) {
root = new Node(key);
return root;
}
/* Otherwise, recur down the tree */
if (key < root.key)
root.left = insertRec(root.left, key);
else if (key > root.key)
root.right = insertRec(root.right, key);
/* return the (unchanged) node pointer */
return root;
}
You can use standard Integer (wrapper for primitive int) object instead of creating a new object type Node. On latest java Integer/int auto-boxing is supported. Hence your method insertNode(int key) can take in Integer argument too (ensure it is not null).
EDIT: Pls ignore above comment. I did not understand your real question. You will have to overload insertNode(). I think you are right.
but where is temp when you insertNode?? With your current implementation temp is lost if root is not null.
I think you want something like
root.getLeft().insertNode(temp);
and
root.getRight().insertNode(temp);
i.e. To insert the new Node (temp) to either the left or the right subtree.

How do I calculate the number of "only child"-nodes in a binary tree?

NOTICE: this is homework-related, but I'm not tagging it as such because the 'homework' tag is marked as obselete (?)
Using the following class that implements a binary tree...
class TreeNode
{
private Object value;
private TreeNode left, right;
public TreeNode(Object initValue)
{
value = initValue;
left = null;
right = null;
}
public TreeNode(Object initValue, TreeNode initLeft, TreeNode initRight)
{
value = initValue;
left = initLeft;
right = initRight;
}
public Object getValue()
{
return value;
}
public TreeNode getLeft()
{
return left;
}
public TreeNode getRight()
{
return right;
}
public void setValue(Object theNewValue)
{
value = theNewValue;
}
public void setLeft(TreeNode theNewLeft)
{
left = theNewLeft;
}
public void setRight(TreeNode theNewRight)
{
right = theNewRight;
}
}
I need to calculate the number of nodes in the binary tree that are "only children," this being defined as a node that doesn't have another node stemming from its parent.
This is what I have so far:
public static int countOnlys(TreeNode t)
{
if(t == null)
return 0;
if(isAnOnlyChild(t))
return 1;
return countOnlys(t.getLeft()) + countOnlys(t.getRight());
}
I don't know how to implement the boolean method isAnOnlyChild(TreeNode t)
Could someone please help me?
You are pretty close and have the traversal looking good but in your Treenode you do not have a link between a child and its parent. So You can not tell from say a left child if a sibling (right child) exists.
You could have a parent Treenode (along with left and right) so you could check how many children a given node's parent has. Or as ajp15243 suggested, instead use a method that checks how many children a given node has.
Some pseudo code of the latter:
//we still need to check if that only child has its own children
if hasOnlyChild(t)
return 1 + checkOnlys(left) + checkOnlys(right)
else
return checkOnlys(left) + checkOnlys(right)
As you have already noticed, one solution is to count number of parents that have only one child. This should work:
public static int countOnlys(TreeNode t)
{
if(t == null || numberOfChildren(t)==0){
return 0;
}
if(numberOfChildren(t)==1){
return 1+ countOnlys(t.getLeft()) + countOnlys(t.getRight());
}
if(numberOfChildren(t)==2 ){
return countOnlys(t.getLeft()) + countOnlys(t.getRight());
}
return 0;
}
public static int numberOfChildren (TreeNode t){
int count = 0;
if(t.getLeft() != null ) count++;
if(t.getRight() != null) count++;
return count;
}
A parent has an only child if exactly one of the children is non-null (which implies that exactly one of its children is null):
((t.getLeft() == null || t.getRight() == null)) && !(t.getLeft() == null && t.getRight() == null)
You don't test, however, the node when you visit it as the recursive code traverses the tree. (This is similar to the Visitor pattern.) What you do is test for an only child when you are sitting on the parent. It's actually a logical exclusive-or test because one and only one of the children needs to be non-null to detect that this node has an only child.
So the algorithm is to
visit each node in the tree.
count it, if the node has only one child
That's it. The rest is plumbing.
public static int onlyChild(TreeNode t){
int res = 0;
if( t != null){
// ^ means XOR
if(t.getLeft() == null ^ t.getRight() == null){
res = 1;
}
res += onlyChild(t.getLeft()) + onlyChild(t.getRight()));
}
return res;
}
whenever you traverse a binary tree, think recursively. this should work.
public static int countOnlys(TreeNode t)
{
if(t == null)
return 0;
if (t.getLeft()==null&&t.getRight()==null)
return 1;
return countOnlys(t.getLeft())+countOnlys(t.getRight());
}
public int countNode(Node root) {
if(root == null)
return 0;
if(root.leftChild == null && root.rightChild == null)
return 0;
if(root.leftChild == null || root.rightChild == null)
return 1 + countNode(root.leftChild) + countNode(root.rightChild);
else
return countNode(root.leftChild) + countNode(root.rightChild);
}

Counting the nodes in a binary search tree

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

Categories

Resources