二叉排序树删除思路:
- 若删除结点为叶子结点,可直接删除。
- 若删除结点左子树为空,那么右子树接上(俗称子承父业)。
- 若删除结点右子树有空,那么左子树接上(依旧是子承父业)。
- 若删除结点左右子树均不为空,那么有两种办法:
第一种是直接按照上面的方法,直接左子树接上,然后将其右子树的结点再一个个插入,这样可能会引起树的高度增加,使得查询效率降低,故我们不采用这种方法。
第二种方法是查找被删除结点A的直接前驱结点B或者是直接后继结点替代,为什么要找直接前驱或者直接后继呢?因为该结点不可能同时存在左子树和右子树,即将问题矛盾转化成上面已经处理过的问题,本文代码处采用直接前驱替代,直接前驱结点B在被删除结点的最左下方,我们找到直接前驱结点B,直接将B的数据替换被删除结点的数据,再将直接前驱结点B删除即可。
typedef struct BiTree{
struct BiTree* lchild;
struct BiTree* rchild;
int data;
}BiTree;
bool BalDelete(BiTree* &bt){
if (bt->lchild == NULL && bt->rchild == NULL) {
BiTree* p = bt;
bt = NULL;
delete p;
}else if(bt->lchild == NULL){
BiTree* p = bt;
bt = bt->rchild;
delete p;
}else if(bt->rchild == NULL){
BiTree* p = bt;
bt = bt->lchild;
delete p;
}else{
BiTree* preParent = bt;
BiTree* pre = bt->lchild;
while(pre->rchild) {
preParent = pre;
pre = pre->rchild;
}
bt->data = pre->data;
if (preParent != bt) {
preParent->rchild = pre->lchild;
}else{
preParent->lchild = pre->lchild;
}
delete pre;
}
return true;
}
bool BalDeleteBST(BiTree* &bt,int data){
if (bt == NULL) {
return false;
}
if (bt->data == data) {
return BalDelete(bt);
}else if(bt->data < data){
return BalDeleteBST(bt->rchild, data);
}else{
return BalDeleteBST(bt->lchild, data);
}
}
bool BalCreateTree(BiTree* &bt, int key){
if (bt == NULL) {
bt = new BiTree();
bt->data = key;
return true;
}else{
if(key == bt->data){
return false;
}else if (key > bt->data) {
return BalCreateTree(bt->rchild, key);
}else{
return BalCreateTree(bt->lchild, key);
}
}
}
bool BalFindData(BiTree* bt,int key){
if (bt == NULL) {
return false;
}
if (key == bt->data) {
return true;
}else if(key > bt->data){
return BalFindData(bt->rchild, key);
}else{
return BalFindData(bt->lchild, key);
}
}
void BiInOrder(BiTree* root){
if (root == NULL) {
return;
}
BiInOrder(root->lchild);
cout<< root->data <<" ";
BiInOrder(root->rchild);
}
int main(int argc, const char * argv[]) {
BiTree* tree = NULL;
int balData[] = {38,12,34,56,13,6,98,17,40,78};
for (int i = 0; i < sizeof(balData)/sizeof(int); i++) {
BalCreateTree(tree, balData[i]);
}
BiInOrder(tree);
cout<<endl;
BalDeleteBST(tree,40);
BiInOrder(tree);
cout<<endl;
BalDeleteBST(tree,34);
BiInOrder(tree);
cout<<endl;
BalDeleteBST(tree,13);
BiInOrder(tree);
cout<<endl;
BalDeleteBST(tree,38);
BiInOrder(tree);
cout<<endl;
BalDeleteBST(tree,12);
BiInOrder(tree);
cout<<endl;
return 0;
}