BST属于对无序集合排序查找算法中的一种,通过定义左小右大的规则放置无序集合中的元素,使得中序遍历能得到排序后的集合,并且任一子树都是二叉排序树。二叉排序树中右子树上任一元素大于该节点上左子树中全部元素,我是通过这个性质,写的删除,也叫后继删除。当然也可以前驱删除,从本质上来说是一样的。二叉排序树的建立、查找都是相当简单的,通过迭代、递归都可以实现,不断判断当前值是否大于小于当前节点,大于往右走,小于往左走,直到走到叶节点。删除要分为3种情况:1、叶节点可直接删除2、若只有右子树,则让右子树的根替换该节点,只有左子树的话同理3、有左右子树,找到删除节点的后继,用后继的值代替要删除节点的值,若后继有右子树又分为两种情况1、删除节点右子树上有左子树,用后继父节点的左指针指向后继的右子树2、删除节点的右子树没有左子树,那么右边的节点就代替了最左的后继,此时用后继父节点的右指针指向后继的右子树。具体就来看一看代码吧
#include<iostream>
#include<ctime>
using namespace std;
struct Node{
int data;
Node* left;
Node* right;
};
void InOrderTranversal(Node* root){
if(root==0){
return;
}
InOrderTranversal(root->left);
cout<<root->data<<endl;
InOrderTranversal(root->right);
}
void release(Node* root){
if(root==0){
return;
}
release(root->left);
release(root->right);
delete root;
}
void search(Node*& root,int key,Node**& _result){
if(root==0){
_result=0;
return;
}
if(key<root->data){
search(root->left,key,_result);
}
else if(key==root->data){
_result=&root;//put purpoes's addr to result for changing the purpoes pointer point another addr by _delete
return;
}
else{
search(root->right,key,_result);
}
}
void insert(Node*& root,int value){
if(root==0){
root=new Node;
root->left=0;
root->right=0;
root->data=value;
return;
}
if(value>root->data){
insert(root->right,value);
}
else if(value==root->data){
return;
}
else{
insert(root->left,value);
}
}
bool _delete(Node*& root,int key){
Node** node;
search(root,key,node);
if(node==0){
return false;
}
Node* temp=*node;
if((*node)->left==0&&(*node)->right==0){//leaf node can remove now
*node=0;
cout<<"0"<<endl;
delete temp;
}
else if((*node)->left==0){//if has no left,make parent link to right and remove itself
*node=(*node)->right;
delete temp;
}
else if((*node)->right==0){
*node=(*node)->left;
delete temp;
}
else{
//it must have left and right
//my method is subsequent move,walk to end of right's left
//s init to right
//s_prent init to root
Node* s=(*node)->right;
Node* s_parent=*node;
while(s->left!=0){
s_parent=s;
s=s->left;
}
temp->data=s->data;
if(s->right!=0){//if end of right's left has right, it should replace end of right's left
if(s_parent==*node){//if s_parent does not change,s_parent has had left tree,so it should put s'right to s_parent's right
s_parent->right=s->right;
}
else{
s_parent->left=s->right;
}
}
else{
if(s_parent==root){
s_parent->right=0;
}
else{
s_parent->left=0;
}
}
delete s;
}
return true;
}
int main(){
srand(time(NULL));
Node* root=new Node;
root->left=0;
root->right=0;
root->data=10;
for(int i=0;i<100;i++){
insert(root,rand()%100);
}
InOrderTranversal(root);
Node** _result;
int value;
cout<<"please cin the value you want to find:";
cin>>value;
search(root,value,_result);
if(_result==0){
cout<<"can't find purpoes!"<<endl;
}
else{
cout<<"the result is:"<<(*_result)->data<<endl;
}
cout<<"please cin the value you want to delete:";
cin>>value;
if(_delete(root,value)){
InOrderTranversal(root);
cout<<"delete succeed!"<<endl;
}
else{
cout<<"delete failed!"<<endl;
}
release(root);
return 0;
}