I am having some trouble understanding the recursive functions involved in preorder, inorder, and postorder tree traversal. I have some knowledge of recursion (but admittedly its not my strong suit). All of the seem to call themselves twice first making a call with the left child of the root and then with the right child. But how exactly is this possible? Wouldn't the call to the preOrder function with the left child return the flow of control back to the top, and the next call would never be executed?
void preOrder (Node* root)
{
if (root == NULL) return;
cout<<root->val<<", ";
preOrder(root->left);
preOrder(root->right);
}
Wouldn't the call to the preOrder function with the left child return the flow of control back to the top, and the next call would never be executed?
Of course not. The recursive call works just like any other function call: after the function completion the control returns to the place of call. 'The place' means not only the point in the code but also the point on the call stack, which means the same set of variables is available again. Just like after returning from any other function.
For example if you have a tree
A
/ \
X Y
and you call preorder on the A node, then it first prints the A contents, then calls preorder on X and on return it is back in preorder(A), so it proceeds to call preorder on Y.
Preorder: Process the node, move to the left child, move to the right child
void preorder(Node *root)
{
if (root == NULL) //<- Check if the currently passed node is empty
return; //<- if it is, return from the function back down the stack
cout << root->val << ", "; //<- if it wasn't empty, print its value
if (root->left != NULL) //<- check if the node to the left is empty
preorder(root->left); //<- if not recurse to the left child
if (root->right != NULL) //<- check if the node to the right is empty
preorder(root->right); //<- if not recurse to the right child
}
Inorder: move to the left, process the node, move to the right
void inorder(Node *root)
{
if (root == NULL)
return;
if (root->left != NULL) //<- check if the node to the left is empty
inorder(root->left); //<- if not recurse to the left child
cout << root->val << ", ";
if (root->right != NULL) //<- check if the node to the right is empty
inorder(root->right); //<- if not recurse to the right child
}
Postorder: Move to the left node, move to the right node, process the node
void postorder(Node *root)
{
if (root == NULL)
return;
if (root->left != NULL) //<- check if the node to the left is empty
postorder(root->left); //<- if not recurse to the left child
if (root->right != NULL) //<- check if the node to the right is empty
postorder(root->right); //<- if not recurse to the right child
cout << root->val << ", "
}
void preorder(node *p) {
if(p) {
cout << p->val <<"\n";
preorder(p->left);
preorder(p->right);
}
}
Related
I am new to recursion concept and while practicing I came across a problem for which I am not able to get a logical reasoning.
For the below code snippet, first element of the link is not getting printed (Assume list has more than one elements).
public void foo(ListNode head) {
foo1(head, head.next);
}
private void foo1(ListNode curr, ListNode nextNode) {
if (nextNode == null) {
return;
}
curr = nextNode;
nextNode = curr.next;
foo1(curr, nextNode);
System.out.println(curr);
}
Now for example if list has 3 elements as 1 -> 2 -> 3 -> null, only 3 and 2 are getting printed. foo method made a call with head element which is one so shouldn't it print 1 aslo in the output.
Please help me understand what I am doing wrong here.
curr = nextNode;
...
System.out.println(curr);
The problem is you set the curr to its successor before you print it.
private void foo1(ListNode curr) {
if (curr == null)
return;
System.out.println(curr);
foo1(curr.next);
}
Reason
The reason is, before printing the first element, your code changes the value from the first element to the second element. One more issue also present in your code, when we pass one element, it won't print that one element also. Because consider this you have a node 5 and the next node is null. When you pass this node to foo1() method, immediately it reaches the condition nextNode is null and it returns, here there is no chance to print the first node 5.
I modified your same code to run perfectly as expected, look below.
public void foo(ListNode head) {
foo1(head, head.next);
}
private void foo1(ListNode curr, ListNode nextNode) {
if(curr != null)
System.out.println(curr);
if (nextNode == null) {
return;
}
curr = nextNode;
nextNode = curr.next;
foo1(curr, nextNode);
}
I'm attempting to use a struct to manage accessing nodes on a tree. Whenever I access the method of the parent's child node, the parent reference on the subsequent call gets lost (i.e. parent.child.method(child) -> [parent becomes nil]-> parent(the previous child).child ... etc).
Here is the error snippet from my file.
type Node struct {
Left *Node
Right *Node
value int
}
func (parent *Node) determineSide(child *Node) (Node, Node) {
if child.Value < parent.Value {
if parent.hasLeftNode() {
return parent.Left.determineSide(child)
}
return parent.addLeftNode(child)
} else if child.Value > parent.Value {
if parent.hasRightNode() {
return parent.Right.determineSide(child)
}
return parent.addRightNode(child)
}
return *child, *parent
}
I attempted to solve this by trying to find a way to inform the method that the new reference should be parent.Left. Things like using *parent.Left and &parent.Left didn't seem to be correct.
A solution may might be to move this code outside of the struct and have another function handle the outcome for a quick fix, but I'd like to understand why this isn't working out of the box. Thought process here is influenced by using this.child.determineSide(child).
Full code is here.
Edit
Here is some output from the terminal that might give even further context. Looks like I'm having a check type issue leading to the problem.
parent &{<nil> <nil> 2}
parent.Left <nil>
parent.LeftNode true
child &{<nil> <nil> 1}
parent <nil>
child &{<nil> <nil> 1}
Okay, I know what u'r exactly asking finally.
New() methods returns a value, not a pointer, which means u can't see later change in caller. What the caller got is only a value copy of the Node. So the parent what u print will always be {Left:<nil> Right:<nil> Value:2}.
So the same with addLeftNode() and addRightNode().
Just use pointer, not value to achieve your goal.
See pointers_vs_values
I think it's just the Visit() method where the problem is.
It will never visit right child when u immediately return after visited left child.
The left and right child are not mutually exclusive, so the second if-clause should not use else if, which would be if.
The visiting order also has problem.
Before:
// Visit will automatically walk through the Child Nodes of the accessed Parent Node.
func (parent *Node) Visit() (Node, int) {
fmt.Println("Node value:", parent.Value)
if parent.hasLeftNode() {
return parent.Left.Visit()
} else if parent.hasRightNode() {
return parent.Right.Visit()
}
return *parent, parent.Value
}
Modified:
// Visit will automatically walk through the Child Nodes of the accessed Parent Node.
func (parent *Node) Visit() (Node, int) {
if parent.hasLeftNode() {
parent.Left.Visit()
}
fmt.Println("Node value:", parent.Value)
if parent.hasRightNode() {
parent.Right.Visit()
}
return *parent, parent.Value
}
Additionally, as to me, Visit() shouldn't return any values.
Problem originated from incorrect type checking. The function successfully handled the call, but the method I was using wasn't accurate in confirming whether a node was assigned.
// isNode checks whether the provided property is a Node.
func (parent *Node) isNode(property interface{}, typeset interface{}) bool {
fmt.Println(reflect.TypeOf(property) == reflect.TypeOf(typeset))
// this always referred to the address for the base Node struct or similar falsy.
return reflect.TypeOf(property) == reflect.TypeOf(typeset)
}
// hasLeftSide tests whether the Parent Node has a Node assigned to its left side.
func (parent *Node) hasLeftNode() bool {
return parent.Left != nil //parent.isNode(parent.Left, (*Node)(nil))
}
// hasRightSide tests whether the Parent Node has a Node assigned to its right side.
func (parent *Node) hasRightNode() bool {
return parent.Right != nil // parent.isNode(parent.Right, (*Node)(nil))
}
Below is my code. I'm trying to return head node back after I insert value to either left or right node. I understood the concept of insertion, but I'm unable to understand how can I return my head node back to that now it is back to original state with addition node added.
Here is exactly I don't understand.
When I insert my node how can I break the loop and return its head node back.
Recursion is stack concept which will output based on LIFO and if it is lifo how can I have head node returned back
Here's my code:
class Node {
int data;
Node left;
Node right;
}
static Node Insert(Node root,int value)
{
return nodeHelper(root,value);
}
static Node nodeHelper(Node root,int value){
Node nodeTracker = root;
Node temp;
if(root!=null){
if(value>root.data){
if(root.right==null){
temp =new Node();
temp.data = value;
root.right = temp;
return nodeTracker;
}
else{
nodeHelper(root.right,value);
}
}
else{
if(root.left==null){
temp=new Node();
temp.data = value;
root.left = temp;
return nodeTracker;
}
else{
nodeHelper(root.left,value);
}
}
}
else{
temp=new Node();
temp.data = value;
return temp;
}
}
}
To return the root of the tree, you need a third parameter that you pass around to keep track of the root. Like this:
Node* nodeHelper(Node* nodeTracker, Node* parent, int value)
Remove the local nodeTracker variable.
Your recursive calls become:
return nodeHelper(nodeTracker, parent.left, value);
(and, of course, same thing for the right branch)
And your initial call in the insert function is:
return nodeHelper(root, root, value);
I attempted writing the following method which tells whether a Binary Tree is Binary Search Tree or not? I pass only half of the test cases. What am I doing wrong?
boolean checkBST(Node root) {
boolean leftflag = false;
boolean rightflag = false;
Node l = root.left;
Node r = root.right;
if(l!=null) {
if(root.data <= l.data) {
leftflag = false;
}
else {
leftflag = true;
checkBST(l);
}
}
if(leftflag == false)
return false;
if(r != null) {
if(root.data >= r.data) {
rightflag = false;
}
else {
rightflag = true;
checkBST(r);
}
}
if(rightflag == false)
return false;
return true;
}
I can see a case where your program could return wrongly false.
Imagine you have a tree with 3 branches deep going as follow :
7
/ \
3 8
\ / \
4 6 9
Your program starts up at 7 (root), creates two boolean at false (leftflag and rightflag), checks if left is null. It isn't. It then checks if the data of left <= the data of right. It is.
So you recursively call your function with a new root node left (3 in the example). Again, it creates your two boolean at false initial value, checks if left node is null. It is ! So it skips the whole if, goes directly to your other if before the return.
// The condition here is respected, there is no left node
// But the tree is an actual search tree, you didn't check right node
// Before returning false.
if(leftflag == false)
return false
What i'd do is
if(l != null)
{
if(root.data<=l.data)
{
return false;
}
else
{
// recursive call here
}
}
if(r != null)
{
// Same as left node here
}
so even if your left node is null, the program still checks for the right node. Hope i helped out a little bit !
Your primary mistake is that you ignore the return value of your recursive calls. For instance:
else {
leftflag = true;
checkBST(l);
}
}
if(leftflag == false)
return false;
If checkBST(l) returns false, you ignore it. You never save the value. Thus, your subsequent check for leftflag is utterly ignorant of the subtree's suitability. Semantically, your routine assumes that all subtrees are BSTs -- you set the flag, recur on the subtree, but don't change the flag. Try this logic:
else
leftflag = checkBST(l)
Now, please get comfortable with Boolean expressions. For instance, testing a Boolean value against a Boolean constant is a little wasteful. Instead of
if (flag == false)
Just check directly:
if (!flag)
Checking a pointer for null is similar in most languages:
if (l)
Finally, don't initialize your flags if you're simply going to set them to the same value as the first action.
Now, your code might appear like this:
boolean leftflag = false;
boolean rightflag = false;
if(l) {
if(root.data > l.data) {
leftflag = checkBST(l);
}
}
if(!leftflag)
return false;
if(r) {
if(root.data < r.data) {
rightflag = checkBST(r);
}
}
if(rightflag == false)
return false;
return true;
}
Now it's a little easier to follow the logic flow. Note that you have a basic failure in your base case: a null tree is balanced, but you return false.
Now, if you care to learn more about logic short-circuiting and boolean expressions, you can reduce your routine to something more like this:
return
(!root.left || // Is left subtree a BST?
(root.data > root.left.data &&
checkBST(root.left)))
&&
(!root.right || // Is right subtree a BST?
(root.data > root.right.data &&
checkBST(root.right)))
In the following code, I'm trying to get a better hand at understanding how recursion actually work. I've always been a bit confused about it's actual working. I want to know what value does the inorder() function actually return in every step. From where does it get these values of 0,0,11,0,0,11,12,0,0,11 respectively. Could someone tell me the logic? It's a basic inorder tree traversal program.The reason why I'm trying to understand these outputs is because the same logic is somehow used to find the depth of the tree( I think) where with every recursion the value of depth increases without initialization.
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *left;
struct node *right;
};
struct node* newNode(int data)
{
struct node* node=(struct node*)malloc(sizeof(struct node));
node->data=data;
node->left=NULL;
node->right=NULL;
return node;
}
int inorder(struct node *temp) {
if (temp != NULL) {
printf("\nleft %d\n",inorder(temp->left));
printf("\n%d\n", temp->data);
printf("\nright %d\n",inorder(temp->right));
}
}
int main()
{
struct node *root=newNode(1);
root->left=newNode(2);
root->right=newNode(3);
root->left->left=newNode(4);
root->left->right=newNode(5);
inorder(root);
getchar();
return 0;
}
This function should be changed to the following (the first and last print in the original code will only get you more confused!):
int inorder(struct node *temp) {
if (temp != NULL) {
inorder(temp->left);
printf("%d\n", temp->data);
inorder(temp->right);
}
}
The recursion starts with the left branch of a specific node (usually the "root") - printing recursively (in-order) all the nodes on that left-branch, then printing the current node, moving on to printing recursively (in-order) all the nodes in the right branch.
By the way, if you want to keep that tree "ordered" (meaning, all the nodes on the left branch are smaller than the node, and all the nodes on the right branch are bigger or equal to the node) you should change:
root->left->left=newNode(4);
root->left->right=newNode(5);
to:
root->right->right=newNode(4);
root->right->right->right=newNode(5);