#include<iostream>
using namespace std;
class Node{
public:
int val;
Node *parent;
Node *left;
Node *right;
};
class binarysearchtree
{
Node *root;
public:
binarysearchtree(){
root =NULL;
}
void insertdata(int val)
{
Node *newnode=new Node;
newnode->val=val;
newnode->parent=NULL;
newnode->left=NULL;
newnode->right=NULL;
if(root==NULL)
{
root=newnode;
}
else{
Node *temp=root;
Node *prev=NULL;
while(temp!=NULL)
{
prev=temp;
if(val < temp->val)
{
temp=temp->left;
}
else{
temp=temp->right;
}
}
temp=newnode;
newnode->parent=prev;
if(val < prev->val)
{
prev->left=newnode;
}
else{
prev->right=newnode;
}
// cout<<prev->val<<" "<<newnode->val<<endl;
}
}
Node* searchdata(int val)
{
Node *temp=root;
while(temp!=NULL)
{
if(temp->val==val) return temp;
if(val<temp->val)
{
temp=temp->left;
}
else
{
temp=temp->right;
}
}
return temp;
}
Node* maximumnode(Node* cur)
{
if(cur==NULL)
{
cout << "Invalid!" << endl;
return cur;
}
Node *temp=cur;
while(temp->right!=NULL)
{
temp=temp->right;
}
cout<<"Maximum node: "<<temp->val<<endl;
return temp;
}
Node* minimumnode(Node* cur)
{
if(cur==NULL)
{
cout << "Invalid!" << endl;
return cur;
}
Node *temp=cur;
while(temp->left!=NULL)
{
temp=temp->left;
}
cout<<"Minimum node: "<<temp->val<<endl;
return temp;
}
void inorder(Node *temp)
{
if(temp==NULL)
{
return;
}
inorder(temp->left);
cout<<temp->val<<" ";
inorder(temp->right);
}
Node* getroot(){
return root;
}
void deletenode(int val)
{
Node* found=searchdata(val);
if(found==NULL)
{
cout<<"Not found"<<endl;
}
else if(found->left==NULL && found->right==NULL)
{
deletecase1(found);
}
else if(found->left==NULL || found->right==NULL)
{
deletecase2(found);
}
else{
deletecase3(found);
}
}
void deletecase1(Node *temp)
{
cout<<"Case 1:"<<endl;
Node *par=temp->parent;
if(temp->val < par->val)
{
par->left=NULL;
}
else{
par->right=NULL;
}
delete temp;
}
void deletecase2(Node *temp)
{
cout<<"Case 2:"<<endl;
Node *par=temp->parent;
Node *child=temp->left;
if(child==NULL)
{
child=temp->right;
}
if(temp->val < par->val)
{
par->left=child;
}
else{
par->right=child;
}
child->parent=par;
delete temp;
}
void deletecase3(Node *temp)
{
Node *suc=findsuccessor(temp);
int temp1 = suc->val;
deletenode(suc->val);
temp->val = temp1;
}
Node* findsuccessor(Node *temp)
{
if(temp==NULL)
{
cout<<"Not found"<<endl;
return NULL;
}
else if(temp->right!=NULL)
{
Node *cur=temp->right;
cur=minimumnode(cur);
cout<<"Successor: "<<cur->val<<endl;
return cur;
}
else if(temp->parent!=NULL){
Node *cur=temp->parent;
while(cur->val < temp->val)
{
temp=cur;
cur=cur->parent;
if(cur==NULL){
cout<<"Not found"<<endl;
return NULL;
}
}
cout<<"Successor: "<<cur->val<< endl;
return cur;
}
else{
cout<<"Not found"<<endl;
return NULL;
}
}
Node* findpredeccessor(Node *temp)
{
if(temp==NULL)
{
cout<<"Not found in the list"<<endl;
return NULL;
}
else if(temp->left!=NULL)
{
Node *cur=temp->left;
cur=maximumnode(cur);
cout<<"Predecessor: "<<cur->val<<endl;
return cur;
}
else if(temp->parent!=NULL){
Node *cur=temp->parent;
while(cur->val > temp->val)
{
temp=cur;
cur=cur->parent;
if(cur==NULL){
cout<<"Not found"<<endl;
return NULL;
}
}
cout<<"Predecessor: "<<cur->val<< endl;
return cur;
}
else{
cout<<"Not found"<<endl;
return NULL;
}
}
};
int main()
{
//freopen("input.txt","r",stdin);
int n;
cin>>n;
binarysearchtree bst;
for(int i=0;i<n;i++)
{
int a;
cin>>a;
bst.insertdata(a);
}
Node *temp=bst.getroot();
bst.inorder(temp);
cout << endl;
int i;
cin>>i;
Node* found=bst.searchdata(i);
if(found==NULL)
{
cout<<"Not found"<<endl;
}
else{
cout<<"found"<<endl;
}
bst.minimumnode(bst.getroot());
bst.maximumnode(bst.getroot());
Node *temp1=bst.getroot();
bst.inorder(temp1);
cout << endl;
int del;
cout<<"Want to del:"<<endl;
cin>>del;
bst.deletenode(del);
Node *temp2=bst.getroot();
bst.inorder(temp2);
cout << endl;
int p;
cout<<"Find the successor: "<<endl;
cin>>p;
Node* found2=bst.searchdata(p);
if(found2==NULL)
{
cout<<"Not found"<<endl;
}
else{
cout<<"found"<<endl;
}
cout<<"Find the successor: "<<endl;
bst.findsuccessor(found2);
int q;
cout<<"Find the predecessor: "<<endl;
cin>>q;
Node* found3=bst.searchdata(q);
if(found3==NULL)
{
cout<<"Not found"<<endl;
}
else{
cout<<"found"<<endl;
}
cout<<"Find the successor: "<<endl;
bst.findpredeccessor(found3);
//bst.inorder(temp2);
// bst.deletecase1();
}
/*
12
44 17 88 32 65 97 28 54 82 29 76 80
82
44
44
54
*/