#include <iostream>
using namespace std;
struct BiTreeNode{
int data;
BiTreeNode* left;
BiTreeNode* right;
BiTreeNode* parent;
};
void InOrderTraverse(BiTreeNode* Root){
if(Root==NULL) return;
InOrderTraverse(Root->left);
cout<<Root->data<<' ';
InOrderTraverse(Root->right);
}
BiTreeNode* Search(BiTreeNode* Root,int key){
while(Root){
if(Root->data==key)
return Root;
else if(Root->data>key)
Root=Root->left;
else
Root=Root->right;
}
return NULL;
}
BiTreeNode* SearchRecur(BiTreeNode* Root,int key){
if(!Root) return NULL;
if(Root->data==key)
return Root;
if(Root->data>key)
return SearchRecur(Root->left,key);
else
return SearchRecur(Root->right,key);
}
BiTreeNode* Minimum(BiTreeNode* Root){
while(Root->left)
Root=Root->left;
return Root;
}
BiTreeNode* Maximum(BiTreeNode* Root){
while(Root->right)
Root=Root->right;
return Root;
}
BiTreeNode* Successor(BiTreeNode* pNode){
if(pNode->right)
return Minimum(pNode->right);
BiTreeNode* pParentNode=pNode->parent;
while(pParentNode && pNode==pParentNode->right){
pNode=pParentNode;
pParentNode=pNode->parent;
}
return pParentNode;
}
BiTreeNode* Predecessor(BiTreeNode* pNode){
if(pNode->left)
return Maximum(pNode->left);
BiTreeNode* pParentNode=pNode->parent;
while(pParentNode && pNode==pParentNode->left){
pNode=pParentNode;
pParentNode=pNode->parent;
}
return pParentNode;
}
void Insert(BiTreeNode** Root,int key){
BiTreeNode* pNew=new BiTreeNode;
pNew->data=key;
pNew->parent=pNew->left=pNew->right=NULL;
BiTreeNode* pParentNode=NULL;
BiTreeNode* pNode=*Root;//important
while(pNode){
pParentNode=pNode;
if(pNode->data>key)
pNode=pNode->left;
else
pNode=pNode->right;
}
pNew->parent=pParentNode;
if(pParentNode==NULL)
*Root=pNew;
else{
if(pParentNode->data>key)
pParentNode->left=pNew;
else
pParentNode->right=pNew;
}
}
void Delete(BiTreeNode** Root,int key){
//get the node whose data to be delete
BiTreeNode* pNode=Search(*Root,key);
//node to delete phisically
BiTreeNode* pDel=NULL;
if(!pNode->left || !pNode->right)
pDel=pNode;
else
//delete the successor(predecessor ok too)
pDel=Successor(pNode);
BiTreeNode* pChild=NULL;
if(pDel->left)
pChild=pDel->left;
else
pChild=pDel->right;
if(pChild)
pChild->parent=pDel->parent;
if(pDel->parent==NULL)
*Root=pChild;
else{
if(pDel==pDel->parent->left)
pDel->parent->left=pChild;
else
pDel->parent->right=pChild;
}
if(pNode!=pDel)
pNode->data=pDel->data;
delete pDel;
pDel=NULL;
}
int main(){
//test
BiTreeNode* Root=NULL;
//insert and traverse
Insert(&Root,4);
Insert(&Root,2);
Insert(&Root,6);
Insert(&Root,3);
Insert(&Root,7);
Insert(&Root,5);
Insert(&Root,1);
InOrderTraverse(Root);
cout<<endl;
//max and min
cout<<Maximum(Root)->data<<endl;
cout<<Minimum(Root)->data<<endl;
//predecessor and successor
cout<<Successor(Minimum(Root))->data<<endl;
cout<<Predecessor(Maximum(Root))->data<<endl;
cout<<Successor(Search(Root,3))->data<<endl;
cout<<Predecessor(Search(Root,5))->data<<endl;
//delete and traverse
Delete(&Root,6);
InOrderTraverse(Root);
cout<<Successor(Search(Root,5))->data<<endl;
Delete(&Root,7);
Delete(&Root,2);
Delete(&Root,3);
Delete(&Root,4);
Delete(&Root,5);
InOrderTraverse(Root);
}