Build Binary Tree from Preorder Traversal: Stack Overflow Error - java

I have a tree where the leaves are marked with L and the non-leaf nodes are marked with I. I am given the preorder traversal of the tree. An example is IIILLILILLIIILLLIILILLL. I have to build the huffman tree for this included string. I originally pass in a new Root(), 0, and my treeString for my arguments. TreeString would be the string with the I's and L's pasted above. For some reason my code causes a StackOverflow exception to be thrown. My code is as follows for the makeTree method:
public static void makeTree (BinaryNodeInterface<Character> root, int start, String treeString)
{
if (treeString.charAt(start)=='L'){
root.setLeftChild(null);
root.setRightChild(null);
return;
}
BinaryNodeInterface<Character> leftSide = new BinaryNode<Character>();
root.setLeftChild(leftSide);
makeTree(root.getLeftChild(), start++, treeString);
BinaryNodeInterface<Character> rightSide = new BinaryNode<Character>();
root.setRightChild(rightSide);
makeTree(root.getRightChild(), start++, treeString);
}
I have no idea what is causing the stackoverflow exception to be thrown. I would think that my base case at the beginning would return and handle it.

I believe this is the problem:
makeTree(root.getLeftChild(), start++, treeString);
I'm not sure what your approach is, but it looks like if you see an I, your plan is to go to the left node, and start examining the string starting at the next character.
The reason for the infinite recursion is that start++ is a post-increment operator, which means that it gives you the current value of start and then increments it. Thus, each time makeTree calls itself, it calls itself with the same version of start, and thus looks at the same I in the input string.
However, changing it to ++start will not make things work. (It might avoid the stack overflow, but it won't work right.) The reason is that when you call makeTree, you want to give it the starting location of the string where you want the recursive call to start looking--but you also want the recursive call to tell it how much of the string it consumed. That is necessary because, after makeTree calls itself recursively on getLeftChild, you will call it again on getRightChild, and you need to call it with the correct starting point.
Note that each recursive invocation has its own copy of start. Thus, when makeTree calls itself, and the second makeTree increments start, this has no effect on the start that the first makeTree sees.
You'll somehow need each recursive makeTree to tell its caller how much of the string it consumed. Probably, the simplest way to do this is to change the return type to int; you can decide whether you want the function result to be the number of characters consumed, or the index where it stopped scanning, or something similar. Then, after calling makeTree recursively, use the function result to adjust the start parameter. Make sure makeTree returns the correct result, both in the leaf and the non-leaf cases. Be careful to avoid off-by-one errors.

You cannot create a tree just from preOrder list.
Atleast you need inorder traversal as well OR if is full tree then you can also use posrorder.

Related

How to understand a recursive inorder traversal of a BST in Java?

I am trying to understand how the well-established methods of implementing an inorder traversal of a binary search tree are functioning in Java.
I am given the following code:
public void inorder() {
if (!this.isEmpty()) {
this.getLeft().inorder();
System.out.print(this.getValue());
this.getRight().inorder();
}
}
with isEmpty() returning whether the current Node is null, getValue() returning the value of the current node, and getLeft() as well as getRight() respectively returning the left and right successor node.
My problem here is, I do not understand how one is able to process the traversal with this code. I have visualized my chain of thoughts on a sheet of paper for you guys to see, with the circles being the nodes, the black squares being null nodes, and the encircled node being the current (this) object. As I am following the pseudocode, I would land in a null node at the end and hit the recursive dead-end case. I also do not at all understand how the code is able to go back in the tree hierarchy once we've already set subtree nodes as the current this object.
My visualization
Am I imagining this wrong, and if so, could someone help me understand the right way of doing this? The code works, but I really need to understand how that comes through. Any help would be super super appreciated
As I am following the pseudocode, I would land in a null node at the end and hit the recursive dead-end case
When you reach the "dead-end" case, this means the current branch of the recursion tree ends. It doesn't mean the entire recursion ends.
After all, when method X calls method Y, and method Y ends, the control returns to method X. This remains true when methods X and Y have the same name. The recursion only ends after the original inorder() call (which was executed on the root of the tree) returns.
You can number each call to the inorder() method in order to tell them apart:
1. root.inorder() calls
2. root.getLeft().inorder() calls
3. root.getLeft().getLeft().inorder() calls
4. root.getLeft().getLeft().getLeft().inorder()
this node is empty, so inorder() #4 method returns control to the previous one (#3)
now #3 call prints the current node via System.out.print(this.getValue())
which prints the left most node of the tree
then #3 calls
5. root.getLeft().getLeft().getRight().inorder()
this node is also empty, so the current inorder() method returns control to #3
now #3 also ends, and returns control to the previous method (#2)
and so on...

Some questions regarding recursion

What is direct recursions? What is infinite recursion?
What is a base case and why is it necessary/important?
example code:
public static void indifferent(int x, int y) {
if (x <= y) {// base case
System.out.print("!");
}else {
System.out.print(x);
indifferent(x - 1, y + 2);
System.out.print(y);
}
}
Direct recursion is when a method calls itself (as in your example code). Indirect recursion is when method a() calls method b(), which itself (either directly or indirectly) calls method a() again.
Infinite recursion is recursion that never ends. Another way of putting it is that infinite recursion is when the base case either does not exist or is never encountered.
A base case is a set of argument values that causes the method to return without a recursive call (either direct or indirect).
Direct recursion: Method invokes itself.
Indirect recursion: Method invokes some other method and after many invocations, the call returns, to a situation where the first calling method is invoked again.
Base case: It is an important component of any recursion function. It is a condition for recursive method to stop calling itself and thus end the recursion i.e. stop going deeper in recursion. Basically, if you think of recursion as a yoyo then it is the base case when the recursion is at its extreme end.
infinite recursion: It is a recursion which never ends. Basically it is a recursive function which does not have a base case. (a yo-yo which doesn't come back and goes all over the place.)
Checkout these interesting recursion images at this link
Here's an algorithm for climbing stairs
climb:
if you are at the top
stop
otherwise
step up and then climb
That shows you direct recursion (climb is a step inside climb) and base case (stop if you are at the top).
Two cases of infinite recursion:
climb:
step up and then climb
climb:
if you are at the top
stop
otherwise
step up and then step down and then climb
The first has no base case and the second will never reach the base case:
Finally, indirect recursion:
group climb:
if there's no one in the group
stop
otherwise
step up
step up:
if first in group is at top
remove them from the group then group climb
otherwise
step up first in group then group climb

Getting the number of the order of the function in a recursive call

What is the easiest way to retrieve the order of the function in a recursive call. For instance, if we have a recursive function, it keeps calling itself until it finds the base case, and then it returns one function at a time. The first function returning is of order 0, the second is of order 1, and so on...What is an easy way to retrieve the order information? Say for instance, when it is the function of order three, I would like to do something special.
Edit: I want the function at the top of the stack to be zero.
Edit2: The problem I am trying to solve is to return the nth element of the in order traversal of a binary tree.
If you are starting with a recursive function that looks like this
void recursive(int p1, String p2, long p3) {
...
if (someCondition) {
recursive(nextP1, nextP2, nextP3);
}
}
change it to this:
void recursive(int p1, String p2, long p3, int level) {
...
if (someCondition) {
recursive(nextP1, nextP2, nextP3, level+1);
}
}
Now Start off the level at zero by calling
recursive(initialP1, initialP2, initialP3, 0);
level will indicate the number of invocation of recursive above you.
EDIT : (zero-at-the-top)
You can also transform the function to return its level to implement the "zero at the top" strategy:
int recursive(int p1, String p2, long p3) {
if (baseCase) {
return 0;
}
...
int level = 0;
if (someCondition) {
level = 1+recursive(nextP1, nextP2, nextP3);
}
return level;
}
Note that in this case you cannot find your level until after the last recursive invocation has returned.
The case dasblink has offered you covers the opposite of what you suggested implementation-wise because the level counter rises (increments) as you go deeper in the recursion.
If you want it to decrease as you go deeper in the recursion that would imply that you know the exact recursion depth beforehand.
In most cases if you know the exact recursion depth you won't be using recursion, you'll be using a loop (for, while, repeat/until etc.). In fact using recursion in such a case is less optimal because of the recursion stack that gets allocated (higher memory consumption) and loops are much more efficient.
If the level 0 should be the last "nested call", then it is in general
undecidable problem similar to the halting problem, because you can't
just say "after 3 more nested calls, the function will return a
value". It is possible to look ahead only by simulating the
computation of the particular function.
If the level 0 should be the first call, then it is quite simple and you can use the level as a param of the method and increment it.
btw, interesting problem, see http://en.wikipedia.org/wiki/Halting_problem

Recursively Search on a Binary Tree

can anybody help me to trace this piece of code if its correct or incorrect.i am studying recursion these days.
boolean search(Element element) {
Element c=first;
if(c==null)
return false;
else if(element.asset < c.asset)
if(c.left==null)
return false;
else
return search(c.left);
else if(element.data>c.data)
if(c.right==null)
return false;
else
return search(c.right);
else
return element.asset==c.asset;
}
it lacks stop condition. you should check if t.left == null, or you will get NullPointerException. also, you should return t.left.isExist(..) OR t.right.isExist(...) and not isExist [you will want to invoke this method on the son]
currently, this version will get into infinite loop - because you will always check in the same root node.
Your code isn't symmetric.
for one side, you call isExist(t.left), for another you call isExist(a.right)
You probably want to call t.left.isExist(a) and t.right.isExist(a), but that is purely speculative as you do not have a complete SSCCE for us to look at.
It is syntactically correct Java. But I don't see how it could possibly be doing what you intend.
It appears that the 'element' parameter is the thing you are searching for and the 'first' field in the current class is the root of the binary tree.
It's unclear if the key for the binary tree and search (in the Element class) is 'asset' or 'data'. The 'less than' test uses 'asset', while the 'greater than' test uses 'data'. It seems likely that both lines should use the same field. It might be that one of these two fields ('asset' or 'data') should not be referenced in this method at all. Maybe the last line of the method should be just 'return true;'?
(I suspect that the "stop condition" and the "code isn't symmetric" answers above are both incorrect. But I could be wrong: It's hard to tell with only the code given.)
I agree that infinite looping is likely: I suspect that you need to create a second 'search' function that accepts two 'Element' parameters -- one being the thing to search for (like the current 'element' parameter) and the other being the next Element to search -- the equivalent of current local variable 'c'. I would do the "Extract Method" refactoring on everything in the body of the current 'search' method except the first line, and then change the two recursive calls to use the new method.
(Some of this is speculative, based on me guessing what you want or intend, given limited information. So I could, of course, be quite wrong.)

Recursion Question : Revision

My slides say that:
A recursive call should always be on a smaller data structure than the current one
There must be a non recursive option if the data structure is too small
You need a wrapper method to make the recursive method accessible
Just reading this from the slides makes no sense, especially seeing as it was a topic from before christmas!
Could anyone try and clear up what it means please?
Thank you
A recurssive call should always be on a smaller data structure than the current one
In general this isn't true but if you are talking about linked lists manipulation with recursion it is. What it is implying is that you need to always be working towards a solution and this usually is dealing with a smaller problem than you started with.
Take for example Quicksort. Each time the function is called it is working with a smaller set of data.
Taking another example of printing a linked list, the next time you call the recursive function the argument should be the tail of the linked list (This code has an error in it, but that leads us to our next point)
void printList(List l){
print(l.head);
printList(l.tail);
}
There must be a non recurssive option if the data structure is too small
This means there should be a base case. The point where the function stops calling itself again.
int factorial(int n){
if ( n == 1 ){ //the base case is when n = 1
return 1;
}
return n*factorial(n-1);
}
Going back to the example of printing a linked list, there has to be a case where you only have an empty list left (in which case the function should do nothing). Going back to the code to print a linked list
void printList(List l){
if ( l.empty == true ){ //the base case is when the list l is empty
return;
}
print(l.head);
printList(l.tail);
}
You need a wrapper method to make the recurssive method accessible
I don't know Java, and it isn't really a language designed for recursion, however in many cases your recursive function will have more parameters than the person using the API should be able to see. You might for example want to have a counter in there.
You can have a wrapper function that simplifies the parameters to just what is needed. The wrapper function then calls the real worker function.
An example might be if we have a linked list class that has the recursive function to print the list. Its declaration would look something like this:
void printList(List l);
However as it is a class method, to someone using the API it doesn't make much sence to have to do this:
myList.printList(myList);
So a wrapper function could be created that doesn't have any paramters which then calls the code that does the work.
void printList(){
doPrintList(this); //pass in the List object as the first argument
}
Then all the programmer using the API has to do is:
myList.printList();

Categories

Resources