Question : Write a function to find inorder successor of a given node in a binary search tree.
Our inclination would be to write tree minimum of right subtree. Because we already use this mechanism while deleting a node with both subtrees.
But what we fail to notice is that tree minimum of right subtree would be present if there IS a right subtree. What if the node has no right child? What if it is a leaf node? Which nodes are successors of these nodes? And how do we find them?
The inorder successor of 3 can be found out as tree minimum of right subtree, which is 4. But what about successors of 4? Or 7? Or successor 13?
One method would be to store parent link in each node. And travel up finding parent nodes until the parent node has a value greater than given node.
But that needs modification of the structure. Another method is to start from root node and search for a given value and store node with larger value as successor and terminate when we come across a node with value matching given node.
e.g. In the tree given above
To find successor of 4, we start with root - successor = 8
Then we branch left and visit node 3 - successor is still 8
Then we branch right and visit node 6 - successor is 6
Then we branch left and we terminate loop
We found our successor as 4
To find successor of 7,
We start with root - successor = 8
We branch to left - successor =8
We branch to right - successor = 8
We branch to right - we found 7 and terminate loop
Successor is 8
Here is the function which covers both the cases i.e. the case where given node has a right child and the case where there is no right child and hence above mechanism is to be used.
Our inclination would be to write tree minimum of right subtree. Because we already use this mechanism while deleting a node with both subtrees.
But what we fail to notice is that tree minimum of right subtree would be present if there IS a right subtree. What if the node has no right child? What if it is a leaf node? Which nodes are successors of these nodes? And how do we find them?
The inorder successor of 3 can be found out as tree minimum of right subtree, which is 4. But what about successors of 4? Or 7? Or successor 13?
One method would be to store parent link in each node. And travel up finding parent nodes until the parent node has a value greater than given node.
But that needs modification of the structure. Another method is to start from root node and search for a given value and store node with larger value as successor and terminate when we come across a node with value matching given node.
e.g. In the tree given above
To find successor of 4, we start with root - successor = 8
Then we branch left and visit node 3 - successor is still 8
Then we branch right and visit node 6 - successor is 6
Then we branch left and we terminate loop
We found our successor as 4
To find successor of 7,
We start with root - successor = 8
We branch to left - successor =8
We branch to right - successor = 8
We branch to right - we found 7 and terminate loop
Successor is 8
Here is the function which covers both the cases i.e. the case where given node has a right child and the case where there is no right child and hence above mechanism is to be used.
NODEPTR successor(NODEPTR root, NODEPTR nd) { if(nd->right!=NULL)/*has right child*/ { nd = nd->right; while(nd->left!=NULL) { nd = nd->left; } return nd; } else { NODEPTR succ = NULL; while(root!=NULL) { if(root->val > nd->val) { succ = root; root = root ->left; } else if(root->val <nd->val) root = root ->right; else return succ; } return root; } }
Also you have to remember the fact that, the right most node - the largest value in a BST has no successor.
Here is complete program
#include<stdio.h> #include<stdlib.h> struct node { int val; struct node *left; struct node *right; }; typedef struct node *NODEPTR; NODEPTR create_node(int num) { NODEPTR temp = (NODEPTR)malloc(sizeof(struct node)); temp->val = num; temp->left = NULL; temp->right = NULL; return temp; } NODEPTR insert_node(NODEPTR nd,NODEPTR newnode) { if(nd==NULL) return newnode;/* newnode becomes root of tree*/ if(newnode->val > nd->val) nd->right = insert_node(nd->right,newnode); else if(newnode->val < nd->val) nd->left = insert_node(nd->left,newnode); return nd; } void in_order(NODEPTR nd) { if(nd!=NULL) { in_order(nd->left); printf("%d---",nd->val); in_order(nd->right); } } NODEPTR search(NODEPTR nd,int num) { while(nd!=NULL ) { if (num > nd->val) nd = nd->right; else if (num< nd->val) nd = nd->left; else return nd; } return NULL;/*not found*/ } NODEPTR successor(NODEPTR root, NODEPTR nd) { if(nd->right!=NULL) { nd = nd->right; while(nd->left!=NULL) { nd = nd->left; } return nd; } else { NODEPTR succ = NULL; while(root!=NULL) { if(root->val > nd->val) { succ = root; root = root ->left; } else if(root->val <nd->val) root = root ->right; else return succ; } return root; } } int main() { NODEPTR root=NULL,delnode; int n; do { NODEPTR newnode; printf("Enter value of node(-1 to exit):"); scanf("%d",&n); if(n!=-1) { newnode = create_node(n); root = insert_node(root,newnode); } } while (n!=-1); printf("\nInorder traversal\n"); in_order(root); while(1) { printf("Enter node value (-1 to stop):"); scanf("%d",&n); if(n==-1) break; NODEPTR nd = search(root,n); if(nd==NULL) printf("%d is not present in tree",n); else { NODEPTR nds = successor(root,nd); if(nds!=NULL) printf("the successor is %d\n",nds->val); else printf("No successor\n"); } } return 0; }
Comments
Post a Comment