So the exercise I am trying to do is:
Write a recursive function to increment by one the value for every node in the binary tree pointed at by "root" then return the modified tree. Assume that nodes store integer values. (-1 means a NULL pointer)
The code I have so far is:
public BinNode BTinc(BinNode root)
{
if (root.right == null && root.left == null){
root.setValue(root.value() + 1);
return root;
}
if (root.left != null) {
root.left.setValue(root.left.value() + 1);
return BTinc(root.left);
}
if (root.right != null) {
root.right.setValue(root.right.value() + 1);
return BTinc(root.right);
}
return root;
}
The problem I am having so far occurs when the root being passed in is -1, in which I get a null pointer exception. I am a bit confused on how this is happening. Is it because I am trying to access the right and left pointers of the null pointer?
in which I get a null pointer exception. I am a bit confused on how
this is happening
you cannot just perform root.setValue(root.value() + 1); because what if the root is null?
you'll need to check if root is not equal to null prior to performing root.setValue.
if (root != null && root.right == null && root.left == null){ // if both left and right nodes are null then simply return root
root.setValue(root.value() + 1);
return root;
}
it's then up to you to set the appropriate value for the root.
Actually, you don't need to check if the left or right node is null or not, it's inefficient. "You do not look at the children to decide whether to make a recursive call." Just access the root and add value and leave the recursive call to do the rest.
public BinNode BTinc(BinNode root){
if (root != null) {
root.setValue(root.value() + 1);
BTinc (root.left());
BTinc (root.right());
}
return root;
}
Related
I'm trying to find a specific node in a binary tree using Java. My method for finding the node returns the node that contains the data that was searched for.
My code looks like this:
public BinNode find(Comparable item) throws NullPointerException {
if (item == null) {
throw new NullPointerException("item is NULL");
} else if (root == null) {
throw new NullPointerException("tree is empty");
}
return find(root, item);
}
public static boolean found = false;
public BinNode find(BinNode k, Comparable item) throws NullPointerException {
if (k.getData().equals(item)) {
found = true;
return k;
}
if (!found && k.getChildLeft() != null) {
find(k.getChildLeft(), item);
}
if (!found && k.getChildRight() != null) {
find(k.getChildRight(), item);
}
return k;
}
Running the debugger I can see, that when I search for an item that exists in the tree, it will find the correct node and go to the first return statement after "found" is set to true.
However, then compiler doesn't return that Node to the method call, but goes on to the second return statement, returning the root. So no matter where the Node is located, the method will always return the root.
What am I doing wrong?
Your method never returns "not found" which is fundamentally wrong because most of the times an item is not in the data. And that is your main problem. You need to return null / an empty Optional in the bottom return statement. And then you need to properly handle that "not found" return value when traversing the tree downwards, namely where you call find for the left and right child.
Your logic has to always be:
has the current node the correct value
if yes return the current node
does the left node contain the value
if yes return the corresponding node from the left
does the right node contain the value
if yes return the corresponding node from the right
return "not found" (because the current node is not correct and neither the left nor the right contain the value)
You currently skip / have not implemented the two nested "if yes return the corresponding node from the left/right" code paths.
(and of course remove the found variable as noted in a comment)
public BinNode find(BinNode k, Comparable item) throws NullPointerException {
if (k.getData().equals(item)) {
return k;
}
if (k.getChildLeft() != null) {
BinNode node = find(k.getChildLeft(), item);
if (node != null) return node;
}
if (k.getChildRight() != null) {
BinNode node = find(k.getChildRight(), item);
if (node != null) return node;
}
return null;
}
You need to return the finds from the left and right calls.
Your code finds the node and returns the k, but the other finds make no returns so your code continues on with code after the conditional statements, which is to return the node k. However, this falls back through the return stack to the original call to the double argument find, which has root as the BinNode given, so that is what is returned.
Refer Luk2302 answer.
You forgot "return" for left and right calls for find() function.
if (!found && k.getChildLeft() != null) {
return find(k.getChildLeft(), item);
}
if (!found && k.getChildRight() != null) {
return find(k.getChildRight(), item);
}
I am trying to write a "contains" method for a splay tree to figure out if a node is already in the tree. I give this method a node to start searching and a string key to use find the corresponding node. I think I have a pretty good handle on recursion, but I am stumped by this. I've bolded the two lines that are causing the infinite recursion, but I'm stuck because, unless you somehow have a tree with an infinite number of elements, wouldn't the left and/or right elements have to be null at some point? They cannot be != to null forever! I might be losing my mind but I would very much appreciate any clarification on how to create a stronger base case.
tldr: how is it possible for this function to recurse infinitely when we have to run into null at some point?!
public BST_Node containsNode(BST_Node node, String s) {
BST_Node result = null;
if (node == null) {
return null;
}
if (node.data.compareTo(s) == 0) {
splay(node);
return node;
}
if (node.left != null) {
result = containsNode(node.left, s); //recursion here
}
if (result == null && node.right != null) {
result = right.containsNode(node.right, s); //recursion here
}
return result;
}
}
I tried to do this using this logic but I am getting error
public static void removeLeaves(BinaryTreeNode<Integer> root) {
BinaryTreeNode<Integer> temp = root;
if (root == null) {
return;
}
if (root.left == null && root.right == null) {
root = null;
}
removeLeaves(temp.left);
removeLeaves(temp.right);
}
Whole tree is getting printed as it is. Please help me out without changing my logic.
In your if statement
if(root.left==null && root.right==null)
{
BinaryTreeNode<Integer> temp = null;
root = temp;
}
You are declaring root as temp, which is null, then pass that temp into the removeLeaves function. So you are passing null into that function when the if statement is true.
BinaryTreeNode<Integer> temp = null;
root = temp;
basically sets root to null and then you call root.left => NPE
You might want to add the necessarily null checks, and probably rethink your function as a whole.
You need to check each root individually for null. Your if statement
if(root.left==null && root.right==null)
{
BinaryTreeNode<Integer> temp = null;
root = temp;
}
only checks if both roots are null. But say there is no left leaf (root.left is null) and there is only a right leaf, you still execute on the left side
removeLeaves(root.left);
However, we already know that root.left is null. I suggest adding individual checks before each call to removeLeaves() or modifying your existing if statement.
I'm not convinced this isn't a homework assignment, but here goes.
The null exception is because you are still calling removeLeaves() even when both the left and right sides are null. Have you tried putting an else after your main IF()?
public static void removeLeaves(BinaryTreeNode<Integer> root)
{
if(root == null)
{
return; // enclosing conditionals in braces is better form, saves lots of headaches later
}
if(root.left==null && root.right==null)
{
BinaryTreeNode<Integer> temp = null;
root = temp;
}
else //at least one is not null
{
removeLeaves(root.left);
removeLeaves(root.right);
}
}
I am using a binary tree structure here. I am getting a "NullPointerException" from the line containing the while statement. I am completely confused about why that would be.
BinaryTreeNode<CharData> currNode = theTree.findValue(data);
// Move up the Binary Tree to create code.
while(currNode.getParent() != null) {
// The loop does some stuff that doesn't
// affect what is assigned to currNode.
// Move to the parent node for the next iteration.
currNode = currNode.getParent();
} // End the while loop.
return code; // Return the string of binary code.
Find value is a method from my BinaryTree class that searches for and finds the node containing specific data. I know this works from testing it separately outside of this implementation.
The only reason why the while-loop statement can throw a NPE is, when currNode is null. I suspect findValue() returned null.
I guess one fix (when you care about the topmost node) would be:
while(currentNode != null) {
rootNode = currentNode;
currentNode = currentNode.getParent();
}
Or the typical pattern which relies on boolean shortcut evaluation:
while(curentNode != null && currentNode.getParent() != null)
Or my prefered solution using guards:
if (currentNode == null)
throw NotFound(); // or return something
while(curentNode.getParent() != null) {
If you see the code:
BinaryTreeNode<CharData> currNode = theTree.findValue(data);
I guess, currNode is getting some value if findValue() able to search data else it is returning NULL values.
When it returns a NULL value it will throw NPE.
To avoid it, you can modify your code a little bit.
while(currNode != null && currNode.getParent != null) {
// your code here
}
I've got a binary tree that should only hold unique string values. Prior to entering a new string (which is done by the user), I need to recursively check the tree to see if the string already exists. Here's the method I've come up with, but it's only finding certain values (the root and the left ones I believe). Any tips on how to fix this are appreciated!
public static TreeNode wordExists(TreeNode root, String strInput){
if (root != null){
if (strInput.equals(root.dataItem))
{
return root;
}
if (root.left != null){
return wordExists (root.left, strInput);
}
if (root.right != null){
return wordExists (root.right, strInput);
}
}
return null;
}
When you navigate down each branch, you need to check the result before returning it. Otherwise, if the result is only in the right branch, but there are other, non-null values in the left, you'll just return null, since it isn't found in the left path.
So instead of
if (root.left != null) {
return wordExists(root.left, strInput);
}
if (root.right != null) {
return wordExists(root.right, strInput);
}
you might do something like
TreeNode result;
if ((result = wordExists(root.left, strInput)) != null) {
return result;
}
return wordExists(root.right, strInput);
You can get away with the shortcut on the second recursion, since, if it fails, you'll just be returning null anyway.