算法导论12(二叉搜索树)

删除:
查找z的直接前驱/后继y,若y是z的左/右孩子,用y替换z;若y不是z的坐/右孩子,先用y的左/右孩子替换y,然后在用y替换z。

struct node
{
    int key;
    node *left,*right,*p;
};

void inorderTreeWalk(node *x)
{
    if(x)
    {
        inorderTreeWalk(x->left);
        cout<<x->key<<' ';
        inorderTreeWalk(x->right);
    }
}

//递归
node *treeSearch(node *x,int k)
{
    if(!x||k==x->key)return x;
    if(k<x->key)return treeSearch(x->left,k);
    else return treeSearch(x->right,k);
}

//迭代
node *iterativeTreeSearch(node *x,int k)
{
    while(x&&k!=x->key)
    {
        if(k<x->key)x=x->left;
        else x=x->right;
    }
    return x;
}

node *treeMinimum(node *x)
{
    while(x->left)x=x->left;
    return x;
}

node *treeMaximum(node *x)
{
    while(x->right)x=x->right;
    return x;
}

node *treeSuccessor(node *x)
{
    if(x->right)return treeMinimum(x->right);
    node *y=x->p;
    while(y&&x==y->right)
    {
        x=y;
        y=y->p;
    }
    return y;
}

node *treePredecessor(node *x)
{
    if(x->left)return treeMaximum(x->left);
    node *y=x->p;
    while(y&&x==y->left)
    {
        x=y;
        y=y->p;
    }
    return y;
}

void treeInsert(node *&root,node *z)
{
    node *y=NULL;
    node *x=root;
    while(x)
    {
        y=x;
        if(z->key<x->key)x=x->left;
        else x=x->right;
    }
    z->p=y;
    if(!y)root=z;
    else if(z->key<y->key)y->left=z;
    else y->right=z;
}

void transplant(node *&root,node *u,node *v)
{
    if(!u->p)root=v;
    else if(u==u->p->left)u->p->left=v;
    else u->p->right=v;
    if(v)v->p=u->p;
}

//直接前驱
void treeDelete(node *&root,node *z)
{
    if(!z->left)transplant(root,z,z->right);
    else if(!z->right)transplant(root,z,z->left);
    else
    {
        node *y=treeMaximum(z->left);
        if(y->p!=z)
        {
            transplant(root,y,y->left);
            y->left=z->left;
            y->left->p=y;
        }
        transplant(root,z,y);
        y->right=z->right;
        y->right->p=y;
    }
    delete z;
}

//直接后继
void treeDelete(node *&root,node *z)
{
    if(!z->left)transplant(root,z,z->right);
    else if(!z->right)transplant(root,z,z->left);
    else
    {
        node *y=treeMinimum(z->right);
        if(y->p!=z)
        {
            transplant(root,y,y->right);
            y->right=z->right;
            y->right->p=y;
        }
        transplant(root,z,y);
        y->left=z->left;
        y->left->p=y;
    }
    delete z;
}

数据结构(C语言版)
删除:
(1)令p的直接前驱/后继替代p,然后再删去p的直接前驱/后继。
(2)若p为f的左子树,令p的左子树为f的左子树,p的右子树为p的直接前驱的右子树;若p为f的右子树,令p的右子树为f的右子树,p的左子树为p的直接后继的左子树。

这里写图片描述

struct node
{
    int value;
    node *left,*right;
};

//直接前驱
void Delete(node *&p)
{
    if(!p->left&&!p->right)delete p;
    else if(!p->left)
    {
        node *q=p->right;
        p->value=q->value;
        p->left=q->left;
        p->right=q->right;
        delete q;
    }
    else if(!p->right)
    {
        node *q=p->left;
        p->value=q->value;
        p->left=q->left;
        p->right=q->right;
        delete q;
    }
    else   
    {
        node *q=p,*s=p->left;
        while(s->right)
        {
            q=s;
            s=s->right;
        }
        p->value=s->value;
        if(q!=p)q->right=s->left;
        else q->left=s->left;
        delete s;
    }
}

//直接后继
void Delete(node *&p)
{
    if(!p->left&&!p->right)delete p;
    else if(!p->left)
    {
        node *q=p->right;
        p->value=q->value;
        p->left=q->left;
        p->right=q->right;
        delete q;
    }
    else if(!p->right)
    {
        node *q=p->left;
        p->value=q->value;
        p->left=q->left;
        p->right=q->right;
        delete q;
    }
    else   
    {
        node *q=p,*s=p->right;
        while(s->left)
        {
            q=s;
            s=s->left;
        }
        p->value=s->value;
        if(q!=p)q->left=s->right;
        else q->right=s->right;
        delete s;
    }
}

void DeleteBST(node *&root,int key)
{
    if(!root)return;
    if(root->value==key)Delete(root);
    else if(root->value<key)DeleteBST(root->left,key);
    else DeleteBST(root->right,key);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值