I'm working on Java Binary Search Tree, and I'm trying to use method findHelp() in find(). I'm expecting a return value of rt.getValue() (which is C2-112, as I print out right before return), but printing out findHelp() in help method returns null.
I couldn't find similar error online, so can someone help me figure out, or give a link to a similar issue?
Here is my code
private E findHelp(BinaryNode<Key, E> rt, Key k) {
int compare = k.compareTo(rt.getKey());
if (compare==0) {
System.out.println(rt.getValue()); // I'm getting C2-112 here
return rt.getValue(); // so I expect a return of C2-112
} else if (compare >0 ) {
if (rt.getRight() == null) {
return null;
} else {
findHelp(rt.getRight(), k);
}
} else {
if (rt.getLeft() == null) {
return null;
} else {
findHelp(rt.getLeft(), k);
}
}
return null;
} //
public E find(Key k) {
E tmp = findHelp(root, k);
System.out.println(tmp); // this prints null, not C2-112
return findHelp(root, k); // and so I return null
}
add a return before every findHelp(...)
Related
I have this homework problem and I have completed all methods except this one, isPerfectlyBalanced().
All my tests pass except one that should return false but instead returns true. I have attached my current code and the test that is failing. Any description on how to go about this or even let me know where my code is wrong is appreciated!
private boolean isPerfectlyBalanced(Node node) {
if (node == null) {
return true;
}
if(size(node.left) == size(node.right)) {
return true;
}
isPerfectlyBalanced(node.left);
isPerfectlyBalanced(node.right);
return false;
}
public boolean isPerfectlyBalancedS() {
// TODO
if (root == null) {
return true;
}
return isPerfectlyBalanced(root);
}
Here is my test that is failing:
assertFalse(set.isPerfectlyBalancedS());
Thank you!
My size method:
private int size(Node node){
if (node == null){
return 0;
} else {
return (size(node.left) + 1 + size(node.right));
}
}
public int size() {
// TODO
return size(root);
}
On the last line of the first method, you probably want to do this:
return (isPerfectlyBalanced(node.left) && isPerfectlyBalanced(node.right));
instead of
isPerfectlyBalanced(node.left);
isPerfectlyBalanced(node.right);
return false;
In your code, you dismiss the result of the isPerfectlyBalanced on the subtrees and always return false.
I am wondering about the base condition in the recursive methods. in my lectures I see that my teacher some times write the base condition in various ways. See this please :
Here the base condition in the public method
public E find(E x) {
if (x == null) {
return null;
}
return find(root,x);
}
private E find(BinaryNode<E> n, E x) {
if (n.element.equals(x)) {
return n.element;
}
else if (x.compareTo(n.element) < 0) {
return find(n.left, x);
}
else {
return find(n.right, x);
}
}
is it OK if I write the base condition in the private method like this :
public E find(E x) {
return find(root,x);
}
private E find(BinaryNode<E> n, E x) {
if (n == null) {
return null;
}
else if (n.element.equals(x)) {
return n.element;
}
else if (x.compareTo(n.element) < 0) {
return find(n.left, x);
}
else {
return find(n.right, x);
}
}
Well, I would pick the following version:
public E find(E x) {
return find(root,x);
}
private E find(BinaryNode<E> n, E x) {
if (n == null) {
return null;
}
else if (n.element.equals(x)) {
return n.element;
}
else if (x.compareTo(n.element) < 0) {
return find(n.left, x);
}
else {
return find(n.right, x);
}
}
Why? Because it's correct. The other one isn't and would lead to the NullPointerException in case there is no such element in the tree.
The second question which appears in the OP post and the comment is whether to put the base condition in a public or a private method. The only possible correct answer is that each recursive method must have a base condition on which the recurrence will end.
public methods can be called by everyone so they should validate the input. They cannot assume that the parameters are valid. private methods can assume that parameters are ok and can focus on their logic.
The condition I would put in your public method would be:
public E find(E x) {
if (<x isn't valid - for example null and nulls are not allowed for values>) {
//do something here - exception or null
}
return find(root,x);
}
It would stand for making sure that the input for the private find...` would be correct. That's what you have to do.
I have below code but when i try to run the check function its giving me stackOverFlow error please help
when i debugged it its going till "return true;", but also entering else.
NOTE :
I have this data in my collection :
{1=[2, 3], 2=[3], 3=[4], 4=[3], 5=[6], 6=[5]}
How can i find the link between two nodes
private Map<Integer, ArrayList<Integer>> graphList = new HashMap<Integer, ArrayList<Integer>>();
private boolean checkLink(ArrayList<Integer> dataListFirst, int match) {
if (dataListFirst != null) {
for (int data : dataListFirst) {
if (data == match) {
return true;
} else {
checkLink(graphList.get(data), match);
}
}
}
return false;
}
You are not using the retun value of your recursive call:
if (data == match) {
return true;
} else {
checkLink(graphList.get(data), match); // <--- Return value unused
}
You can modify your code to check if the recursive calls find your element:
private boolean checkLink(ArrayList<Integer> dataListFirst, int match) {
if (dataListFirst != null) {
for (int data : dataListFirst) {
if (data == match || checkLink(graphList.get(data), match)) {
return true;
}
}
}
return false;
}
This code still could has a problem if your graph has cycles, you could return false in your function when you are trying to check the same value again.
// Just call the recursive function with an empty list of elements
private boolean checkLink(ArrayList<Integer> dataListFirst, int match) {
return checkLink(dataListFirst, match, new ArrayList<Integer>());
}
private boolean checkLink(ArrayList<Integer> dataListFirst, int match, List<Integer> nodes) {
if (dataListFirst != null) {
for (int data : dataListFirst) {
if (nodes.contains(data)) {
return false;
}
nodes.add(data);
if (data == match || checkLink(graphList.get(data), match, nodes)) {
return true;
}
}
}
return false;
}
It seems to me you only want to make a recursive call after checking all the elements of the current ArrayList. And you should use the value returned by the recursive call (that's the reason your recursion didn't end after return true;) :
private boolean checkLink(ArrayList<Integer> dataListFirst, int match)
{
if (dataListFirst != null) {
for (int data : dataListFirst) {
if (data == match) {
return true;
}
}
for (int data : dataListFirst) {
boolean found = checkLink(graphList.get(data), match);
if (found)
return found;
}
}
return false;
}
I'm not sure this will work in all cases, though, since if there are cycles in the graph you may get into an infinite recursion without ever finding the desired node.
I'm new to recursion and I don't see why this function won't compile. It is apparently missing a return statement. From testing it also seems as though my return statements do not return?
// recursive search method
public BinaryTree<T> recursiveSearch(BinaryTree<T> t, T key) {
if (key.compareTo(t.getData()) < 0) {
if (t.getLeft() != null) {
recursiveSearch(t.getLeft(), key);
} else {
return null;
}
} else if (key.compareTo(t.getData()) > 0) {
if (t.getRight() != null) {
recursiveSearch(t.getRight(), key);
} else {
return null;
}
} else if (key.compareTo(t.getData()) == 0) { // key is found
return t;
} else { // not in binary tree
return null;
}
}
The problem is on the lines inside the if branches that make recursive calls.
Your code will behave correctly when it reaches any of your else branches, because all of them have return null. If code takes one of the if branches, however, the control would reach the end of your method without hitting a return. The fix is simple - add the missing returns:
return recursiveSearch(t.getRight(), key);
Yes, it is missing a return statement for the recursion statements.
public BinaryTree<T> recursiveSearch(BinaryTree<T> t, T key)
{
if (key.compareTo(t.getData())<0){
if (t.getLeft() != null) {
recursiveSearch(t.getLeft(), key); // This case doesn't return anything
} else { return null;}
} else if (key.compareTo(t.getData())>0) {
if (t.getRight() != null) {
recursiveSearch(t.getRight(), key); // This case doesn't return anything
} else {return null;}
} else if (key.compareTo(t.getData())==0){ // key is found
return t;
} else {
//not in binary tree
return null;
}
}
I dont know your program logic, but if I have to guess, you might wanna add a return statement to the recursive calls. Like so,
return recursiveSearch(t.getLeft(), key);
and
return recursiveSearch(t.getRight(), key);
I have a method which returns the value of my POJO.
My POJO class's name is Tail.
public Tail getTail(long value1, String value2, int value3) {
List<Tail> l = /*I get this list via Hibernate. */
if (l.size() == 1) {
return (Tail) l.get(0);
}
else if (l.size() > 1) {
for (Tail t : l) {
First ik = minorDAO.getFirst(value3, t.getNumber());
if( ik.getCond().equals("I") ){
t.setCond("I");
continue;
} else {
return t; //???????????????
}
}
} else {
return null;
}
}
In the else statement inside of the foreach loop where the question mark comment is I want to return t, but if I do this, I get an error stating:
"This method must return a result of type Tail".
How can I return the value there?
with that code you dont get the message:
public Tail getTail(long value1, String value2, int value3) {
List<Tail> l = --> (I get list via Hibernate.)
if (l.size() == 1) {
return (Tail) l.get(0);
} else if (l.size()>1){
for (Tail t: l) {
First ik = minorDAO.getFirst(value3, t.getNumber());
if( ik.getCond().equals("I") ){
t.setCond("I");
continue;
} else {
return t;
}
}
}
return null;
}
If the method has to return Tail you must deliver it in any possible case.
For example:
if each element is true in this case:
if( ik.getCond().equals("I") ){
there would be no return. You iterate about the whole list and nothing happens...