#include<bits/stdc++.h>
using namespace std;
class Node
{
public:
int value;
Node* left;
Node* right;
Node* parent;
Node(int value)
{
this->value = value;
this->left = NULL;
this->right = NULL;
this->parent = NULL;
}
};
class Binary_Search_Tree
{
public:
Node* root = NULL;
void insert_data(int value)
{
Node* newnode = new Node(value);
if(!root)
{
root = newnode;
return;
}
Node* temp = root;
Node* prev = NULL;
while(temp)
{
prev = temp;
if(value < temp->value)
temp = temp->left;
else
temp = temp->right;
}
temp = newnode;
newnode->parent = prev;
if(value > prev->value)
prev->right = newnode;
else
prev->left = newnode;
}
void inorder(Node* temp)
{
if(!temp)
return;
inorder(temp->left);
cout << temp->value << " ";
inorder(temp->right);
}
void preorder(Node* temp)
{
if(!temp)
return;
cout << temp->value << " ";
preorder(temp->left);
preorder(temp->right);
}
void posteorder(Node* temp)
{
if(!temp)
return;
posteorder(temp->left);
posteorder(temp->right);
cout << temp->value << " ";
}
Node* search_data(int value)
{
Node* temp = root;
while(temp)
{
if(temp->value == value)
return temp;
else if(temp->value > value)
temp = temp->left;
else
temp = temp->right;
}
return NULL;
}
Node* max_value(Node* temp)
{
if(!temp)
return NULL;
while(temp->right)
{
temp = temp->right;
}
return temp;
}
Node* min_value(Node* temp)
{
if(!temp)
return NULL;
while(temp->left)
{
temp = temp->left;
}
return temp;
}
void delete_node(int value)
{
Node* found = search_data(value);
if(!found)
cout << "Not in the bst\n";
else if(!found->left and !found->right)
delete_case1(found);
else if(!found->left or !found->right)
delete_case2(found);
else
delete_case3(found);
}
void delete_case1(Node* temp)
{
Node* parent = temp->parent;
if(temp->value > parent->value)
parent->right = NULL;
else
parent->left = NULL;
delete temp;
}
void delete_case2(Node* temp)
{
Node* parent = temp->parent;
Node* child = temp->left;
if(!child)
child = temp->right;
if(temp->value < parent->value)
parent->left = child;
else
parent->right = child;
child->parent = parent;
delete temp;
}
void delete_case3(Node* temp)
{
Node* suc = find_succesor(temp);
int value = suc->value;
delete_node(suc->value);
temp->value = value;
}
Node* find_succesor(Node* temp)
{
if(!temp)
return NULL;
else if(!temp->right)
return min_value(temp->right);
else if(temp->parent)
{
Node* cur = temp->parent;
while(cur->value < temp->value)
{
temp = cur;
cur = cur->parent;
if(!cur)
return NULL;
}
return cur;
}
else
return NULL;
}
Node* find_predeccessor(Node* temp)
{
if(!temp)
return NULL;
else if(!temp->left)
return max_value(temp->left);
else if(temp->parent)
{
Node* cur = temp->parent;
while(cur->value > temp->value)
{
temp = cur;
cur = cur->parent;
if(!cur)
return NULL;
}
return cur;
}
else
return NULL;
}
};
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
Binary_Search_Tree B;
int n;
cin >> n;
for(int i = 0; i < n; i++)
{
int x;
cin >> x;
B.insert_data(x);
}
B.inorder(B.root);
// cout << endl;
// B.preorder(B.root);
//Node* a = B.search_data(44);
//Node* a = B.max_value(B.root);
// Node* a = B.min_value(B.root);
// if(a)
// cout << a->value << endl;
// else
// cout << "Not Found\n";
cout << endl;
B.delete_node(17);
B.delete_node(97);
B.inorder(B.root);
return 0;
}