[Naive Approach] Maintaining predecessor and successors - O(n) Time and O(1) Space
We traverse the tree and maintain two values for predecessor and successors and compare the current node's value with both of them.
Traverse the tree and keep track of predecessor and successor values.
If predecessor < node.data < key, update the predecessor. If successor > node.data > key, update the successor.
C++
//Driver Code Starts#include<iostream>#include<vector>usingnamespacestd;// Node StructureclassNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};//Driver Code Ends// traversal to find // predecessor and successorvoidpreorder(Node*root,intkey,Node*&pre,Node*&suc){if(root==nullptr)return;if(root->data<key&&(pre==nullptr||pre->data<root->data)){pre=root;}if(root->data>key&&(suc==nullptr||suc->data>root->data)){suc=root;}preorder(root->left,key,pre,suc);preorder(root->right,key,pre,suc);}// return vector with predecessor at // index 0 and successor at index 1vector<Node*>findPreSuc(Node*root,intkey){Node*pre=nullptr;Node*suc=nullptr;preorder(root,key,pre,suc);return{pre,suc};}//Driver Code Startsintmain(){// Create BST:// 50 // / \ // 30 70// / \ / \ // 20 40 60 80intkey=65;Node*root=newNode(50);root->left=newNode(30);root->right=newNode(70);root->left->left=newNode(20);root->left->right=newNode(40);root->right->left=newNode(60);root->right->right=newNode(80);vector<Node*>result=findPreSuc(root,key);Node*pre=result[0];Node*suc=result[1];cout<<(pre?to_string(pre->data):"NULL")<<" ";cout<<(suc?to_string(suc->data):"NULL")<<endl;}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.ArrayList;importjava.util.Arrays;// Node StructureclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=right=null;}}classGFG{//Driver Code Ends// return ArrayList with predecessor at index 0 // and successor at index 1staticArrayList<Node>findPreSuc(Noderoot,intkey){Node[]pre=newNode[1];Node[]suc=newNode[1];preorder(root,key,pre,suc);returnnewArrayList<>(Arrays.asList(pre[0],suc[0]));}// traversal to find predecessor and successorstaticvoidpreorder(Noderoot,intkey,Node[]pre,Node[]suc){if(root==null)return;if(root.data<key&&(pre[0]==null||pre[0].data<root.data)){pre[0]=root;}if(root.data>key&&(suc[0]==null||suc[0].data>root.data)){suc[0]=root;}preorder(root.left,key,pre,suc);preorder(root.right,key,pre,suc);}//Driver Code Startspublicstaticvoidmain(String[]args){// Create BST:// 50 // / \// 30 70// / \ / \// 20 40 60 80intkey=65;Noderoot=newNode(50);root.left=newNode(30);root.right=newNode(70);root.left.left=newNode(20);root.left.right=newNode(40);root.right.left=newNode(60);root.right.right=newNode(80);ArrayList<Node>result=findPreSuc(root,key);Nodepre=result.get(0);Nodesuc=result.get(1);System.out.print((pre==null)?"NULL ":(pre.data+" "));System.out.print((suc==null)?"NULL ":(suc.data+" "));}}//Driver Code Ends
Python
#Driver Code Starts# Node StructureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None#Driver Code Ends# traversal to find predecessor and successordefpreorder(root,key,pre,suc):ifrootisNone:returnifroot.data<keyand(pre[0]isNoneorpre[0].data<root.data):pre[0]=rootifroot.data>keyand(suc[0]isNoneorsuc[0].data>root.data):suc[0]=rootpreorder(root.left,key,pre,suc)preorder(root.right,key,pre,suc)# return list with predecessor at index 0 and successor at index 1deffindPreSuc(root,key):pre=[None]suc=[None]preorder(root,key,pre,suc)return[pre[0],suc[0]]#Driver Code Startsif__name__=="__main__":# Create BST:# 50 # / \# 30 70# / \ / \# 20 40 60 80key=65root=Node(50)root.left=Node(30)root.right=Node(70)root.left.left=Node(20)root.left.right=Node(40)root.right.left=Node(60)root.right.right=Node(80)result=findPreSuc(root,key)pre=result[0]suc=result[1]print((str(pre.data)ifpreelse"NULL"),(str(suc.data)ifsucelse"NULL"))#Driver Code Ends
C#
//Driver Code StartsusingSystem;usingSystem.Collections.Generic;// Node StructureclassNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=right=null;}}classGFG{//Driver Code Ends// return List with predecessor at index 0 // and successor at index 1staticList<Node>findPreSuc(Noderoot,intkey){Node[]pre=newNode[1];Node[]suc=newNode[1];preorder(root,key,pre,suc);returnnewList<Node>{pre[0],suc[0]};}// traversal to find // predecessor and successorstaticvoidpreorder(Noderoot,intkey,Node[]pre,Node[]suc){if(root==null)return;if(root.data<key&&(pre[0]==null||pre[0].data<root.data)){pre[0]=root;}if(root.data>key&&(suc[0]==null||suc[0].data>root.data)){suc[0]=root;}preorder(root.left,key,pre,suc);preorder(root.right,key,pre,suc);}//Driver Code StartspublicstaticvoidMain(){// Create BST:// 50 // / \// 30 70// / \ / \// 20 40 60 80intkey=65;Noderoot=newNode(50);root.left=newNode(30);root.right=newNode(70);root.left.left=newNode(20);root.left.right=newNode(40);root.right.left=newNode(60);root.right.right=newNode(80);List<Node>result=findPreSuc(root,key);Nodepre=result[0];Nodesuc=result[1];Console.Write((pre==null?"NULL ":pre.data+" "));Console.Write((suc==null?"NULL ":suc.data+" "));}}//Driver Code Ends
JavaScript
//Driver Code Starts// Node StructureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}//Driver Code Ends// traversal to find predecessor and successorfunctionpreorder(root,key,pre,suc){if(root===null)return;if(root.data<key&&(pre[0]===null||pre[0].data<root.data)){pre[0]=root;}if(root.data>key&&(suc[0]===null||suc[0].data>root.data)){suc[0]=root;}preorder(root.left,key,pre,suc);preorder(root.right,key,pre,suc);}// return array with predecessor at index 0 and successor at index 1functionfindPreSuc(root,key){letpre=[null];letsuc=[null];preorder(root,key,pre,suc);return[pre[0],suc[0]];}//Driver Code Starts// Driver code// Create BST:// 50 // / \// 30 70// / \ / \// 20 40 60 80letkey=65;letroot=newNode(50);root.left=newNode(30);root.right=newNode(70);root.left.left=newNode(20);root.left.right=newNode(40);root.right.left=newNode(60);root.right.right=newNode(80);letresult=findPreSuc(root,key);letpre=result[0];letsuc=result[1];console.log((pre?pre.data:"NULL")+" "+(suc?suc.data:"NULL"));//Driver Code Ends
Output
60 70
[Expected Approach-1] Using Two Traversals - O(h) Time and O(1) Space
We traverse the tree twice — once to find the predecessor and once to find the successor.
For predecessor ,
if root < key, then root becomes the predecessor and we search for larger value.
if root >= key, then as predecessor < key, therefore we search in left subtree.
For successor,
if root <= key, then as successor > key, therefore we search in right subtree.
if root > key, and then root becomes the successor and we search for smaller value.
C++
//Driver Code Starts#include<vector>#include<iostream>usingnamespacestd;// Node StructureclassNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=right=nullptr;}};//Driver Code Ends// Finding predecessor of keyNode*findPredecessor(Node*root,intkey){Node*predecessor=NULL;while(root){if(key>root->data){// potential predecessorpredecessor=root;// look for larger predecessorsroot=root->right;}else{root=root->left;}}returnpredecessor;}// Finding successor of keyNode*findSuccessor(Node*root,intkey){Node*successor=NULL;while(root){if(key<root->data){// potential successorsuccessor=root;// look for smaller successorroot=root->left;}else{root=root->right;}}returnsuccessor;}// return vector with predecessor at index 0 // and successor at index 1vector<Node*>findPreSuc(Node*root,intkey){Node*pre=findPredecessor(root,key);Node*suc=findSuccessor(root,key);return{pre,suc};}//Driver Code Startsintmain(){// Create BST:// 50 // / \ // 30 70// / \ / \ // 20 40 60 80Node*root=newNode(50);root->left=newNode(30);root->right=newNode(70);root->left->left=newNode(20);root->left->right=newNode(40);root->right->left=newNode(60);root->right->right=newNode(80);intkey=65;vector<Node*>result=findPreSuc(root,key);Node*pre=result[0];Node*suc=result[1];cout<<(pre?to_string(pre->data):string("NULL"))<<" "<<(suc?to_string(suc->data):string("NULL"));return0;}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.ArrayList;importjava.util.Arrays;// Node StructureclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=right=null;}}classGFG{//Driver Code Ends// return ArrayList with predecessor at index 0 // and successor at index 1staticArrayList<Node>findPreSuc(Noderoot,intkey){Nodepredecessor=findPredecessor(root,key);Nodesuccessor=findSuccessor(root,key);returnnewArrayList<>(Arrays.asList(predecessor,successor));}// Finding predecessor of keystaticNodefindPredecessor(Noderoot,intkey){Nodepredecessor=null;while(root!=null){if(key>root.data){// potential predecessorpredecessor=root;// look for larger predecessorsroot=root.right;}else{root=root.left;}}returnpredecessor;}// Finding successor of keystaticNodefindSuccessor(Noderoot,intkey){Nodesuccessor=null;while(root!=null){if(key<root.data){// potential successorsuccessor=root;// look for smaller successorsroot=root.left;}else{root=root.right;}}returnsuccessor;}//Driver Code Startspublicstaticvoidmain(String[]args){// Create BST:// 50 // / \// 30 70// / \ / \// 20 40 60 80intkey=65;Noderoot=newNode(50);root.left=newNode(30);root.right=newNode(70);root.left.left=newNode(20);root.left.right=newNode(40);root.right.left=newNode(60);root.right.right=newNode(80);ArrayList<Node>result=findPreSuc(root,key);Nodepre=result.get(0);Nodesuc=result.get(1);System.out.print((pre!=null?pre.data:"NULL")+" ");System.out.print(suc!=null?suc.data:"NULL");}}//Driver Code Ends
Python
#Driver Code Starts# Node StructureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None#Driver Code Ends# Finding predecessor of keydeffindPredecessor(root,key):predecessor=Nonewhileroot:ifkey>root.data:# potential predecessorpredecessor=root;# look for larger predecessorsroot=root.rightelse:root=root.leftreturnpredecessor# Finding successor of keydeffindSuccessor(root,key):successor=Nonewhileroot:ifkey<root.data:# potential successorsuccessor=root# look for smaller successorroot=root.leftelse:root=root.rightreturnsuccessor# return list with predecessor at index 0 # and successor at index 1deffindPreSuc(root,key):return[findPredecessor(root,key),findSuccessor(root,key)]#Driver Code Startsif__name__=='__main__':# Create BST:# 50 # / \# 30 70# / \ / \# 20 40 60 80root=Node(50)root.left=Node(30)root.right=Node(70)root.left.left=Node(20)root.left.right=Node(40)root.right.left=Node(60)root.right.right=Node(80)key=65pre,suc=findPreSuc(root,key)print((pre.dataifpreelse"NULL"),(suc.dataifsucelse"NULL"))#Driver Code Ends
C#
//Driver Code StartsusingSystem;usingSystem.Collections.Generic;// Node StructureclassNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=right=null;}}classGFG{//Driver Code Ends// Finding predecessor of keystaticNodefindPredecessor(Noderoot,intkey){Nodepredecessor=null;while(root!=null){if(key>root.data){// potential predecessorpredecessor=root;// look for larger predecessorsroot=root.right;}else{root=root.left;}}returnpredecessor;}// Finding successor of keystaticNodefindSuccessor(Noderoot,intkey){Nodesuccessor=null;while(root!=null){if(key<root.data){// potential successorsuccessor=root;// look for smaller successorsroot=root.left;}else{root=root.right;}}returnsuccessor;}// return List with predecessor at index 0 // and successor at index 1staticList<Node>findPreSuc(Noderoot,intkey){Nodepre=findPredecessor(root,key);Nodesuc=findSuccessor(root,key);returnnewList<Node>{pre,suc};}//Driver Code StartsstaticvoidMain(){// Create BST:// 50 // / \// 30 70// / \ / \// 20 40 60 80Noderoot=newNode(50);root.left=newNode(30);root.right=newNode(70);root.left.left=newNode(20);root.left.right=newNode(40);root.right.left=newNode(60);root.right.right=newNode(80);intkey=65;List<Node>result=findPreSuc(root,key);Nodepre=result[0];Nodesuc=result[1];Console.WriteLine($"{(pre != null ? pre.data.ToString() : "NULL")} "+$"{(suc != null ? suc.data.ToString() : "NULL")}");}}//Driver Code Ends
JavaScript
//Driver Code Starts// Node StructureclassNode{constructor(x){this.data=x;this.left=this.right=null;}}//Driver Code Ends// Finding predecessor of keyfunctionfindPredecessor(root,key){letpredecessor=null;while(root){if(key>root.data){// potential predecessorpredecessor=root;// look for larger predecessorsroot=root.right;}else{root=root.left;}}returnpredecessor;}// Finding successor of keyfunctionfindSuccessor(root,key){letsuccessor=null;while(root){if(key<root.data){// potential successorsuccessor=root;// look for smaller successorroot=root.left;}else{root=root.right;}}returnsuccessor;}// return array with predecessor at index 0 // and successor at index 1functionfindPreSuc(root,key){return[findPredecessor(root,key),findSuccessor(root,key)];}//Driver Code Starts// Driver Code// Create BST:// 50 // / \// 30 70// / \ / \// 20 40 60 80letroot=newNode(50);root.left=newNode(30);root.right=newNode(70);root.left.left=newNode(20);root.left.right=newNode(40);root.right.left=newNode(60);root.right.right=newNode(80);letkey=65;let[pre,suc]=findPreSuc(root,key);console.log((pre?pre.data:"NULL")+" "+(suc?suc.data:"NULL"));//Driver Code Ends
Output
60 70
[Expected Approach-2] Using Single Traversal - O(h) Time and O(1) Space
The idea is to traverse the BST once to find both the predecessor and successor of a given key.
If node < key, it can be the predecessor, so move to the right subtree to find a larger value still < key.
If node > key, it can be the successor, so move to the left subtree to find a smaller value still > key.
If node = key, predecessor is the maximum in left subtree and successor is the minimum in right subtree.
C++
//Driver Code Starts#include<vector>#include<iostream>usingnamespacestd;// Node StructureclassNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=right=nullptr;}};//Driver Code EndsNode*rightMost(Node*node){while(node->right)node=node->right;returnnode;}Node*leftMost(Node*node){while(node->left)node=node->left;returnnode;}// return vector with predecessor at index 0 // and successor at index 1vector<Node*>findPreSuc(Node*root,intkey){Node*pre=NULL;Node*suc=NULL;Node*curr=root;while(curr){if(curr->data<key){pre=curr;// look for predecessor with greater valuecurr=curr->right;}elseif(curr->data>key){suc=curr;// look for successor with smaller valuecurr=curr->left;}else{if(curr->left)pre=rightMost(curr->left);if(curr->right)suc=leftMost(curr->right);break;}}return{pre,suc};}//Driver Code Startsintmain(){intkey=65;// Create BST:// 50 // / \ // 30 70// / \ / \ // 20 40 60 80Node*root=newNode(50);root->left=newNode(30);root->right=newNode(70);root->left->left=newNode(20);root->left->right=newNode(40);root->right->left=newNode(60);root->right->right=newNode(80);vector<Node*>result=findPreSuc(root,key);Node*pre=result[0];Node*suc=result[1];cout<<(pre?to_string(pre->data):"NULL")<<" ";cout<<(suc?to_string(suc->data):"NULL");}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.ArrayList;// Node StructureclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=right=null;}}classGFG{//Driver Code EndsstaticNoderightMost(Nodenode){while(node.right!=null){node=node.right;}returnnode;}staticNodeleftMost(Nodenode){while(node.left!=null){node=node.left;}returnnode;}// return ArrayList with predecessor at index 0 // and successor at index 1staticArrayList<Node>findPreSuc(Noderoot,intkey){Nodepre=null,suc=null;Nodecurr=root;while(curr!=null){if(curr.data<key){pre=curr;// look for predecessor with greater valuecurr=curr.right;}elseif(curr.data>key){suc=curr;// look for successor with smaller valuecurr=curr.left;}else{if(curr.left!=null)pre=rightMost(curr.left);if(curr.right!=null)suc=leftMost(curr.right);break;}}ArrayList<Node>result=newArrayList<>();result.add(pre);result.add(suc);returnresult;}//Driver Code Startspublicstaticvoidmain(String[]args){intkey=65;// Create BST:// 50 // / \// 30 70// / \ / \// 20 40 60 80Noderoot=newNode(50);root.left=newNode(30);root.right=newNode(70);root.left.left=newNode(20);root.left.right=newNode(40);root.right.left=newNode(60);root.right.right=newNode(80);ArrayList<Node>result=findPreSuc(root,key);Nodepre=result.get(0);Nodesuc=result.get(1);System.out.print((pre==null)?"NULL ":(pre.data+" "));System.out.print((suc==null)?"NULL ":(suc.data+" "));}}//Driver Code Ends
Python
#Driver Code Starts# Node StructureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None#Driver Code EndsdefrightMost(node):whilenode.right:node=node.rightreturnnodedefleftMost(node):whilenode.left:node=node.leftreturnnode# return list with predecessor at index 0 # and successor at index 1deffindPreSuc(root,key):pre,suc=None,Nonecurr=rootwhilecurr:ifcurr.data<key:pre=curr# look for predecessor with greater valuecurr=curr.rightelifcurr.data>key:suc=curr# look for successor with smaller valuecurr=curr.leftelse:ifcurr.left:pre=rightMost(curr.left)ifcurr.right:suc=leftMost(curr.right)breakreturn[pre,suc]#Driver Code Startsif__name__=="__main__":key=65# Create BST:# 50 # / \# 30 70# / \ / \# 20 40 60 80root=Node(50)root.left=Node(30)root.right=Node(70)root.left.left=Node(20)root.left.right=Node(40)root.right.left=Node(60)root.right.right=Node(80)pre,suc=findPreSuc(root,key)print((pre.dataifpreelse"NULL"),(suc.dataifsucelse"NULL"))#Driver Code Ends
C#
//Driver Code StartsusingSystem;usingSystem.Collections.Generic;// Node StructureclassNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=right=null;}}classGfG{//Driver Code EndsstaticNodeRightMost(Nodenode){while(node.right!=null)node=node.right;returnnode;}staticNodeLeftMost(Nodenode){while(node.left!=null)node=node.left;returnnode;}// return List with predecessor at index 0 // and successor at index 1publicstaticList<Node>FindPreSuc(Noderoot,intkey){Nodepre=null,suc=null;Nodecurr=root;while(curr!=null){if(curr.data<key){pre=curr;// look for predecessor with greater valuecurr=curr.right;}elseif(curr.data>key){suc=curr;// look for successor with smaller valuecurr=curr.left;}else{if(curr.left!=null)pre=RightMost(curr.left);if(curr.right!=null)suc=LeftMost(curr.right);break;}}returnnewList<Node>{pre,suc};}//Driver Code StartspublicstaticvoidMain(){intkey=65;// Create BST:// 50 // / \// 30 70// / \ / \// 20 40 60 80Noderoot=newNode(50);root.left=newNode(30);root.right=newNode(70);root.left.left=newNode(20);root.left.right=newNode(40);root.right.left=newNode(60);root.right.right=newNode(80);List<Node>result=FindPreSuc(root,key);Nodepre=result[0];Nodesuc=result[1];Console.Write((pre==null?"NULL ":pre.data+" "));Console.Write((suc==null?"NULL":suc.data.ToString()));}}//Driver Code Ends
Javascript
//Driver Code Starts// Node StructureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}//Driver Code EndsfunctionleftMost(node){while(node.left)node=node.left;returnnode;}functionrightMost(node){while(node.right)node=node.right;returnnode;}// return array with predecessor at index 0 // and successor at index 1functionfindPreSuc(root,key){letpre=null,suc=null;letcurr=root;while(curr){if(curr.data<key){pre=curr;// look for predecessor with greater valuecurr=curr.right;}elseif(curr.data>key){suc=curr;// look for successor with smaller valuecurr=curr.left;}else{if(curr.left)pre=rightMost(curr.left);if(curr.right)suc=leftMost(curr.right);break;}}return[pre,suc];}//Driver Code Starts// Driver code// Create BST:// 50 // / \// 30 70// / \ / \// 20 40 60 80letkey=65;letroot=newNode(50);root.left=newNode(30);root.right=newNode(70);root.left.left=newNode(20);root.left.right=newNode(40);root.right.left=newNode(60);root.right.right=newNode(80);let[pre,suc]=findPreSuc(root,key);console.log((pre?pre.data:"NULL")+" "+(suc?suc.data:"NULL"));//Driver Code Ends