删除分为两种可能:
1.只有左子树,或右子树,或叶结点。
q=p; p=p->left; free(q);
叶结点、只有右子树的情况相似。
2.有左子树和右子树的情况
先看完整代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int Delete(Tree &p) { Tree q,s; if(p->right==NULL)/*只有左子树*/ { q=p; p=p->left; free(q); } else if(p->left==NULL)/*只有右子树*/ { q=p; p=p->right; free(q); } else { q=p; s=p->left; while(s->right) { q=s; s=s->right; } p->data=s->data; if(q!=p) { q->right=s->left; } else q->left=s->left; free(s); } return TRUE; } int DeleteBSF(Tree &T,int key) { if(!T) return FALSE; else { if(key==T->data) return Delete(T); else if(key<T->data) return DeleteBSF(T->left,key); else return DeleteBSF(T->right,key); } }
先将s移到待删节点的前驱,方法是:先左转,再一直右转。如图所示,s左转,然后接着右转,结果右转直接为空。此时的状态是:p=q; s=p->left。
另一种情况,右树不为空,一直往前移动,这个时候的规律是:p总指向s的父结点。操作如下:
q->left=s->left; free(s);
删除的五种可能样式:
/*------二叉排序树的查找、插入操作------*/ #include <iostream> using namespace std; #define TRUE 1 #define FALSE 0 typedef struct node { int data; struct node *left,*right; }*Tree,Node; int Delete(Tree &p) { Tree q,s; if(p->right==NULL)/*只有左子树*/ { q=p; p=p->left; free(q); } else if(p->left==NULL)/*只有右子树*/ { q=p; p=p->right; free(q); } else { q=p; s=p->left; while(s->right) { q=s; s=s->right; } p->data=s->data; if(q!=p) { q->right=s->left; } else q->left=s->left; free(s); } return TRUE; } int DeleteBSF(Tree &T,int key) { if(!T) return FALSE; else { if(key==T->data) return Delete(T); else if(key<T->data) return DeleteBSF(T->left,key); else return DeleteBSF(T->right,key); } } int Search(Tree &T,int key,Tree f,Tree &p)/*查找*/ { if(!T)/*最后一步依然没有找到等于key的数据*/ { p=f;/*f必定是叶子结点*/ return FALSE; } else if(key==T->data) { p=T;/*指向等于key的数据*/ cout<<"f->data="<<f->data<<endl; return TRUE; } else if(key<T->data) { return Search(T->left,key,T,p); } else return Search(T->right,key,T,p); } int Insert(Tree &T,int key,Tree &p)/*插入*/ { Tree s; if(!Search(T,key,NULL,p))/*如果没有key这个数据*/ { s=(Tree)malloc(sizeof(Node)); s->data=key; s->left=s->right=NULL; if(!p)/*如果是棵空树*/ { T=s;/*s就为根结点*/ } else if(key<p->data) { p->left=s; } else if(key>p->data) { p->right=s; } return TRUE; } return FALSE; } void Traverse(Tree &T)/*遍历*/ { if(T) { Traverse(T->left); cout<<T->data<<" "; Traverse(T->right); } } int main() { Tree T=NULL,p; int a[]={5,6,7,2,4,10}; for(int i=0;i<sizeof(a)/sizeof(a[0]);i++) Insert(T,a[i],p); Traverse(T); DeleteBSF(T,4); cout<<"删除结点后:"<<endl; Traverse(T); return 0; }