#include <iostream>
#include<stack>
using namespace std;
class node{
friend class tree;
public:
node* left;
int data;
node* right;
node* parent;
};
class tree{
public:
node* root;
tree(){
root=NULL;
}
void insertBtree(int elem);
void inorder(tree* T);
node* find_min(node* N);
node* search_node(tree* T,int elem);
void deletBtree(tree* T,int elem);
void transparent(tree*T,node *u,node *v);
};
void tree::insertBtree(int elem){
node* newNode=new node();
newNode->data=elem;
newNode->left=newNode->right=NULL;
if(root==NULL){
root=newNode;
root->parent=NULL;
}
else{
node* cur=root;
node* par;
while(cur!=NULL){
par=cur;
if(cur->data>elem) cur=cur->left;
else cur=cur->right;
}
if(par->data>elem){par->left=newNode;newNode->parent=par;}
else {
par->right=newNode;
newNode->parent=par;
}
}
}
void tree::inorder(tree* T){//中序遍历
stack<node*> s;
node* cur=T->root;
while(cur!=NULL||s.size()!=0){//向左侧走
while(cur!=NULL){
s.push(cur);
cur=cur->left;
}
if(s.size()!=0){//栈不空,访问栈顶,如果有右孩子,右孩子进栈,继续下一轮寻栈左孩子的循环
cout<<s.top()->data;
node* r=s.top();
s.pop();
if(r->right) s.push(r->right);
}
}
}
node* tree::find_min(node* N){
node *cur=N->right;
while(cur->left!=NULL){
cur=cur->left;
}
return cur;
}
node* tree::search_node(tree* T,int elem){
node *cur=T->root;
while(cur->data!=elem&&cur!=NULL){
if(cur->data>elem) cur=cur->left;
else if(cur->data<elem) cur=cur->right;
}
return cur;
}
void tree::transparent(tree *T,node *u,node *v){//以一棵以V为根的子树替换一棵以U为根的子树
if(u->parent==NULL) //u是树根
T->root=v;
else if(u==u->left)
u->parent->left=v;
else u->parent->right=v;
if (v!=NULL)
v->parent=u->parent;
}
void tree::deletBtree(tree* T,int elem){
node* cur=search_node(T,elem);
node *del,*s;
if(cur!=NULL){
if(cur->left==NULL){//左子树为空,把右子树接到父节点上
transparent(T,cur,cur->right);
}
else if(cur->right==NULL){//右子树为空,把左子树接到父节点上
transparent(T,cur,cur->left);
}
else {
del=find_min(cur);//左右子树都存在,找到右子树最小的节点(后继节点)
if(del->parent!=cur){//后继节点不是删除节点的右孩子
transparent(T,del,del->right);
del->right=cur->right;
del->right->parent=del;
}
transparent(T,cur,del);//后继节点是删除节点的右孩子
del->left=cur->left;
del->left->parent=del;
}
}
}
int main(){
tree* T=new tree();
T->insertBtree(2);
T->insertBtree(1);
T->insertBtree(3);
T->inorder(T);
T->deletBtree(T,2);
T->inorder(T);
}