I'm trying this question for sometime but couldn't figure out the algorithm. My preference is to do it iteratively. Till now, I've figure out something but not sure on some point.
Currently, My algorithm looks like:
May be there are many flaws in this algorithm as still I've not understand all the cases properly. If anyone has any idea or algorithm please share.
Thanks in advance.
when you find a node in preorder, to find its successor is just travesing to its next node.
what I was thinking first is the relationship of a node and its successor's values in pre-oder, but I found that it seems not very clear like the relationship in in-order. I think there is only one step beteen a node and its successor(if exists) : just move on travesing. So I design this algorithm.
my algorithm below is based on preorder travesal, it can run on a binary tree,not only BST.
#define NOT_FOUND -1
#define NEXT 0
#define FOUND 1
struct node {
struct node *p;//parent,but useless here
struct node *l;//left child
struct node *r;//right child
int value;
};
int travese(struct node* bnode, int* flag,int value)
{
if(bnode == NULL)
return 0;
else
{
if(*flag == FOUND)
//when the successor is found,do pruning.
return 1;
else if(*flag == NEXT) {
printf("successor:%d\n",bnode->value);
*flag = FOUND;
return 1;
}
else if(*flag == NOT_FOUND && bnode->value == value)
*flag = NEXT;
travese(bnode->l,flag,value);
travese(bnode->r,flag,value);
}
return 0;
}
and use it by:
int flag = NOT_FOUND;
travese(root,&flag,value);
if(flag == NEXT || flag == NOT_FOUND)
printf("no successor.\n");
EDIT:
turning a recurrence algorithm to a iterative one is not difficult by using a stack like below:
int preorder_travese_with_stack(struct node* bnode, int* flag,int value)
{
if(bnode == NULL)
return 0;
struct stack s;//some kind of implement
push(s,bnode);
while(NotEmpty(s) && *flag) {
struct node *curNode = pop(s);
if(*flag == NEXT) {
printf("successor:%d\n",curNode->value);
*flag = FOUND;
return 1;
}
else if(*flag == NOT_FOUND && curNode->value == value)
*flag = NEXT;
push(s,curNode->r);
push(s,curNode->l);
}
return 0;
}
but according to your comment and original description, I think the one you want is iterative algorithm without a stack.here it is.
After thinking ,searching and trying, I wrote one. When travse the tree iteratively without stack , the parent of a node is not useless any more. In a path, some nodes is visited not only once, and you need to record its direction at that time.
int preorder_travese_without_stack(struct node *root,int value,int *flag)
{
int state=1;
//state: traveral direction on a node
//1 for going down
//2 for going up from its left chlid
//3 for going up from its right child
struct node *cur = root;
while(1) {
if(state == 1) //first visit
{
//common travese:
//printf("%d ",cur->value);
if(cur->value == value && *flag == NOT_FOUND)
*flag = NEXT;
else if (*flag==NEXT) {
*flag = FOUND;
printf("successor:%d\n",cur->value);
break;
}
}
if((state == 1)&&(cur->l!=NULL))
cur = cur->l;
else if((state==1)&&(cur->l==NULL))
{
state = 2;
continue;
}
else if(state==2) {
if(cur->r != NULL ) {
cur=cur->r;
state = 1;
}
else
{
if(cur->p!=NULL)
{
if(cur==cur->p->r)
state = 3;
//else state keeps 2
cur=cur->p;
}
else //cur->p==NULL
{
if(cur->p->r!=NULL)
{
cur=cur->p->r;
state = 1;
}
else
break;
//end up in lchild of root
//because root's rchild is NULL
}
}
continue;
}
else //state ==3
{
if(cur->p!=NULL)
{
if(cur==cur->p->l)
state = 2;
else
state = 3;
cur=cur->p;
continue;
}
else
break;
}
}
}
the usage is the same as the first recurrence one.
If you are confused yet,mostly about the direction of a node , you can draw a tree and draw the path of pre-order traverse on paper,it would help.
I'm not sure there are bugs left in the code,but it works well on the tree below:
0
/ \
1 2
/ \ / \
3 4 5 6
btw,"wirte down pre-order (or else) travese algorithm of a tree both by recurrence and iteration" is a common interview problem, although solving the latter by a stack is permitted.but I think the BST requirement is unnecessary in pre-order travese.