Recursion in binary tree to traverse the entire tree - java

I am studying binary trees. I saw online a code to traverse the entire binary tree. Here's the code I got:
'''
public void showAll(Node node)
{
Node parent = node;
if(parent != null)
{
System.out.println(" " + parent.person);
showAll(parent.leftChild);
showAll(parent.rightChild);
}
}
'''
What I dont understand is how this function can print the right child? According to code everytime the function is called left child is printed. The code never reaches the right child.

This is a textbook implementation of postorder traversal. Also known by some as "bottom up" traversal.
For each iteration the leftmost node then the rightmost node is printed. If the parent node is ever null then the tree is past the highest node, i.e. the algorithm has finished.

Try to dry run the code with binary tree having, say 5 nodes. And then you'll probably figure it out. Even then if you are facing problems, learn a little about how a compiler calls functions or what actually stacktrace is.

Related

Is it possible to change the "find the minimal node" function to also delete the minimal node in a binary search tree?

Just a disclamer, I am doing this for a homework, it's mainly focused on effiency of data structures though.
For a binary search tree i need to implement the delete function, i already created the main traversal system and the only thing i am left doing is to swap the values of a root with the minimal value of it's right subtree, in the case of left and right children. The way i am doing that is through a find the minimal node function.
public int findMin (Tree r1){
int min = r1.key;
while (r1.l != null) {
min = root.l.num;
r1 = r1.l;
}
return min;
}
Great, i found the node i am supposed to delete, my question is, is there a way to also delete the minimal node, without having to traverse the whole tree up until that same node again? Maybe through the function again? Does this function also delete the node or is that not parsed through

Binary Search Tree - adding every node into one result

I try to add every node into one result in iterate way in Java.
For example: if I have a root 5 which has got right node = 7 and left node=3 the result is 15.
I've tried in many ways but I don't know how not to miss any node when my tree is extensive.
I would be grateful for every tip.
Look up tree traversals. There are three basic types: in-order, pre-order, and post-order. Essentially you need to create a function that accepts a node as a parameter and returns an integer.
Assuming you have a node like this:
struct Node {
int value;
Node *right, *left;
}
Something like this would do the trick.
int tree_sum(Node *root) {
if (root == nullptr) return 0; // stops recursion. occurs at leaves
return root->value + tree_sum(root->left) + tree_sum(root->right);
}
Call the function on the root of your tree. This is known as a pre-order traversal. I wrote the code in C++ because I don't know Java.
For tree traversal without recursion use a stack as described here:
https://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion/

StackOverFlow Error when converting 1,000,000 Nodes in a Splay Tree to a SinglyLinkedList

I have implemented a Splay Tree class that uses nodes to store data. In this class I have tried to convert the data of nodes into a Singly Linked List. 1,000,000 nodes can be inserted into the splay tree and it works perfectly. Using recursion I get a StackOverFlow error when the tree contains 1,000,000 nodes. However when the tree contains around 15000 nodes it is able to be converted to a linked list without a problem.
Here is the code for my toList Method that is inside the splay tree class
public LinkedList<Node> toList() {
LinkedList<Node> list = new LinkedList<Node>();
Node node = root;
addToList(node, list);
return list;
}
private void addToList(Node node, LinkedList<Node> list) {
if(node != null) {
addToList(node.left, list);
list.add(node);
addToList(node.right, list);
}
}
I used this test class below to test the function of this method
#Test
public void testConversionToLinkedList {
SplayTree<Integer,String> st = new SplayTree<Integer,String>();
for(int i = 0; i < 1000000; i++) {
st.insert(i, Integer.toString(i));
}
assertEquals(1000000, st.size());
LinkedList<Node> list = st.toList();
assertEquals(1000000, list.size());
}
The test passes when the size entered is around 15000, however any number greater than that will show a StackOverFlowError
The error occurs at the line addToList(node.left, list);
This is really weird because when i used the same recursion technique to print the data of the nodes into a txt file, there is no StackOverFlow error and the data prints perfectly.
I have tried to use In Order Traversal, PreOrder and PostOrder but I still receive the same error at 1,000,000 nodes. I do know that it could be doing recursion too deeply and the stack runs out of memory. If that is the case is there any way I can convert a splay tree of nodes into a linked list?
Any idea what could be going wrong? cheers
Your poblem is the recursive algorithm. As you figured out there is a limit in the stack size, which is build when you have recursion.
You can always transform recursion to a loop.
here are some examples for DFS and BFS algorithms using loops: Non recursive Depth first search algorithm
You can increase the stack’s size. To do it you have to pass parameter to the jvm.
The format is -Xss[g|G|m|M|k|K].
For example: java -Xss4m YourTreeProgram
The root issue is that splay trees can have a height equal to their node count, so the recursive algorithms you often see applied to binary trees are risky when applied to splay trees.
The easiest approach is to splay the tree as you go.
Find the tree's minimum node. Simply follow the "left" links from the root all the way until they are null. Splay this node to the root, then add it to your list.
Find its successor. I.e. follow the root's "right" link once, then follow "left" repeatedly until null. Splay that node to the root, then add it to your list.
Repeat step 2 until there is no successor (i.e. the root's "right" link is null).
Finding the minimum and successor nodes are no different from other kinds of trees.

Understanding Recursion logic

I really need your help for me to understand recursion properly. I can understand basic recursions and their logic like fibonacci
int factorial(int n)
if(n <=1)
return n
else
return(n*factorial(n-1))
That's easy the function keep calling factorial until n becomes zero and finally multiply all the results. But recursions like tree traversal is hard for me to understand
void inorderTraverse(Node* head)
if(head!=NULL){
inorderTraverse(head->left)
cout << head-> data
inorderTraverse(head->right)
}
}
Here I lost the logic how does this function goes if first recursion call will go back to function how can it goes to cout line or how can it show right child data. I really need your help.
Thank you
A binary search tree in alphabetical order:
B
/ \
A C
inorderTraverse(&A) will first descend to A and print it (recursively printing any subtree), then print B, then descend to C and print it (recursively printing any subtree).
So in this case, A B C.
For a more complicated tree:
D
/ \
B E
/ \
A C
This will be printed as A B C D E. Notice how the original tree is on the left of D, so is printed in its entirety first; the problem is reduced to a smaller instance of the starting problem. This is the essence of recursion. Next D is printed, then everything on the right of D (which is just E).
Note that in this implementation, the nodes don't know about their parent. The recursion means this information is stored on the call stack. You could replace the whole thing with an iterative implementation, but you would need some stack-like data structure to keep track of moving back up through the tree.
Inorder traversal says you need to traverse as Left-Root-Right.So for one level it is fine we print in left-root-right format. But With the level increases you need to makesure your algorithm traverse in the same way.So you need to print the leftSubtree first then the root of that subTree and then the right subTree at each level.
The Recursive code inorderTraverse(head->left) tells till the node is not null go to its leftside of the tree.Once it reaches the end it prints the left node then print the Root node of that subTree and wahtever operation u performed on leftSubTree you need to perform the same on Right subTree that's why you write inorderTraverse(head->right). Start debugging by creating 3level trees. Happy Learning.
Try to imagine binary tree and then start traversing it from root. You always go left. If there is no more lefts then you go right and after that you just go up. And you will finish back in root (from right side).
It is similar as going thought maze. You can choose that you will always go to left. (you will always touch left wall). At the end you will finish in exit or back in entrance if there isn't another exit.
In this code is important that you have two recursive calls in body. First is for left subtree and second is for right subtree. When you finish one function returns you back to node where you started.
Binary search trees have the property that for every node, the left subtree contains values that are smaller than the current node's value, and the right subtree contains values that are larger.
Thus, for a given node to yield the values in its subtree in-order the function needs to:
Handle the values less than the current value;
Handle its value;
Handle the values greater than the current value.
If you think of your function initially as a black box that deals with a subtree, then the recursion magically appears
Apply the function to the left subtree;
Deal with the current value;
Apply the function to the right subtree.
Basically, the trick is to initially think of the function as a shorthand way to invoke an operation, without worrying about how it might be accomplished. When you think of it abstractly like that, and you note that the current problem's solution can be achieved by applying that same functionality to a subset of the current problem, you have a recursion.
Similarly, post-order traversal boils down to:
Deal with all my children (left subtree, then right subtree, or vice-versa if you're feeling contrary);
Now I can deal with myself.

leaf to root bst traversal

I was just wondering, given a node which points to its left and right children, is it possible to somehow get an inorder print of the whole bst tree?
All i know about the tree is that it is BST.
And all I know about the node is that he knows who his children are (left and right).
I don't have access to neither the root nor the father of the node.
The node chosen is picked randomly, and I need to return an inorder of the whole tree.
I think there is not enough info to get started at, and my friend got this question during a job interview, and was wondering if that was an unsolvable question or is there a trick I don't know about?
Thanks in advance for any help :)
The only thing you can do from this situation is to travel downwards, because you have no pointer to the parent node. The only case when you can print the whole tree is when the node considered is the root.
So, you can get the inorder print of the subtree rooted at the current node. If this node is the root, then it prints the whole tree. If it is not, then it does not.
Just in case, inorder print is simple:
def inorder(node):
if node == null: return
inorder(node.left)
print node.data
inorder(node.right)

Categories

Resources