#include<stdio.h>
#include<stdlib.h>
/* A binary tree tNode has data, pointer to left child
and a pointer to right child */
struct tNode
{
int data;
struct tNode* left;
struct tNode* right;
};
/* Function to traverse binary tree without recursion and
without stack */
int MorrisRightToLeft(struct tNode *root,struct tNode **currCopy,struct tNode **prev)
{
struct tNode *current,*pre;
int val;
if(root == NULL)
return;
current = root;
if(*prev)
{
pre=*prev;
}
if(*currCopy)
{
current=*currCopy;
}
while(current != NULL)
{
if(current->right == NULL)
{
val=current->data;
current = current->left;
*prev=pre;
*currCopy=current;
return val;
}
else
{
/* Find the inorder predecessor of current */
pre = current->right;
while(pre->left != NULL && pre->left != current)
pre = pre->left;
/* Make current as right child of its inorder predecessor */
if(pre->left == NULL)
{
pre->left = current;
current = current->right;
}
/* Revert the changes made in if part to restore the original
tree i.e., fix the right child of predecssor */
else
{
pre->left = NULL;
val=current->data;
current = current->left;
*prev=pre;
*currCopy=current;
return val;
} /* End of if condition pre->right == NULL */
} /* End of if condition current->left == NULL*/
} /* End of while */
return -1;
}
void MorrisLeftToRight(struct tNode *root,int N)
{
struct tNode *current,*pre;
struct tNode *currCopy=NULL,*prev=NULL;
int l=0,r=0,label,label2;
if(root == NULL)
return;
current = root;
r= MorrisRightToLeft(root,&currCopy,&prev);
while(current != NULL)
{
if(current->left == NULL)
{
l = current->data;
label1 : if(l!=r && l+r == N)
{
printf("\n\nSum1 found %d + %d = %d",l
,r
,N
); return;
}
else if(l==r)
{
printf("\n\nSum Does Not Exits"); break;
}
else if(l + r > N)
{
r= MorrisRightToLeft(root,&currCopy,&prev);
if(r==-1)
{
printf("\nCannot find sum\n"); break;
}
goto label1;
//continue;
}
current = current->right;
}
else
{
/* Find the inorder predecessor of current */
pre = current->left;
while(pre->right != NULL && pre->right != current)
pre = pre->right;
/* Make current as right child of its inorder predecessor */
if(pre->right == NULL)
{
pre->right = current;
current = current->left;
}
/* Revert the changes made in if part to restore the original
tree i.e., fix the right child of predecssor */
else
{
pre->right = NULL;
l = current->data;
label2 : if(l!=r && l+r == N)
{
printf("\n\nSum2 found %d + %d = %d",l
,r
,N
); return;
}
else if(l==r)
{
printf("\n\nSum Does Not Exits"); break;
}
else if(l + r < N)
{
r= MorrisRightToLeft(root,&currCopy,&prev);
if(r==-1)
{
printf("\nCannot find sum\n"); break;
}
goto label2;
// continue;
}
current = current->right;
} /* End of if condition pre->right == NULL */
} /* End of if condition current->left == NULL*/
} /* End of while */
}
/* UTILITY FUNCTIONS */
/* Helper function that allocates a new tNode with the
given data and NULL left and right pointers. */
struct tNode* newtNode(int data)
{
struct tNode* tNode = (struct tNode*)
tNode->data = data;
tNode->left = NULL;
tNode->right = NULL;
return(tNode);
}
/* Driver program to test above functions*/
int main()
{
/* Constructed binary tree is
1
/ \
2 3
/ \
4 5
*/
struct tNode *root = newtNode(50);
root->left = newtNode(30);
root->right = newtNode(55);
root->left->left = newtNode(10);
root->left->right = newtNode(35);
int N=80;
MorrisLeftToRight(root,N);
return 0;
}