二叉排序树:删除操作

删除分为两种可能:
1.只有左子树,或右子树,或叶结点。

q=p;
p=p->left;
free(q);

叶结点、只有右子树的情况相似。

2.有左子树和右子树的情况

先看完整代码:

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);
    }
}
View Code

先将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;
}
原文地址:https://www.cnblogs.com/tinaluo/p/5303096.html