14-C. DS二叉排序树之删除

14-动态查找与查找二叉树-
题目描述
给出一个数据序列,建立二叉排序树,并实现删除功能

对二叉排序树进行中序遍历,可以得到有序的数据序列

输入
第一行输入t,表示有t个数据序列

第二行输入n,表示首个序列包含n个数据

第三行输入n个数据,都是自然数且互不相同,数据之间用空格隔开

第四行输入m,表示要删除m个数据

从第五行起,输入m行,每行一个要删除的数据,都是自然数

以此类推输入下一个示例

输出
第一行输出有序的数据序列,对二叉排序树进行中序遍历可以得到

从第二行起,输出删除第m个数据后的有序序列,输出m行

以此类推输出下一个示例的结果

输入样例
1
6
22 33 55 66 11 44
3
66
22
77

输出样例
11 22 33 44 55 66
11 22 33 44 55
11 33 44 55
11 33 44 55

提示
当删除数据不在序列中,那么删除操作等于不执行,所以输出序列不变化

#include<iostream>
using namespace std;

struct node
{
    int data;
    struct node *lchild;
    struct node *rchild;
};

class BSTtree
{
    node tree[20];
    node *temp=new node();
    node *pp=new node();
public:
    BSTtree()
    {
        tree->data=-1;
        tree->lchild=tree->rchild=NULL;
    }
    void creattree()
    {
        int n,i,e,m;
        cin>>n;
        for(i=0;i<n;i++)
        {
            cin>>e;
            if(tree->data==-1)
                tree->data=e;
            else
                insert(tree,e);
        }
        inorder(tree);
        cout<<endl;//输出有序的数据序列->对二叉排序树进行中序遍历
        
        cin>>m;//输出删除第m个数据后的有序序列
        for(i=0;i<m;i++)
        {
            cin>>e;
            if(search(tree,e)==1)//删除数据在序列中
                deletee(temp,e);
            inorder(tree);
            //cout<<i<<endl;
            cout<<endl;
        }
    }
    void insert(node *p,int e)
    {
        node *x=new node();
        if(e>p->data && p->rchild==NULL)//没有子树直接插入
        {
            x->data=e;
            x->lchild=x->rchild=NULL;
            p->rchild=x;
        }
        else if(e<p->data && p->lchild==NULL)
        {
            x->data=e;
            x->lchild=x->rchild=NULL;
            p->lchild=x;
        }
        else if(e>p->data && p->rchild!=NULL)//有子树递归
            insert(p->rchild,e);
        else if(e<p->data && p->lchild!=NULL)
            insert(p->lchild,e);
    }
    void inorder(node *p)//中序遍历
    {
        if(p->lchild!=NULL)
            inorder(p->lchild);
        cout<<p->data<<" ";
        if(p->rchild!=NULL)
            inorder(p->rchild);
    }
    int search(node *p,int e)
    {
        if(e==p->data)
        {
            temp=p;//temp=要删除的数据
            return 1;
        }
        else if(e>p->data)
        {
          if(p->rchild==NULL)
               return -1;
          if(p->rchild->data==e)
              if(p->rchild->lchild==NULL && p->rchild->rchild==NULL)
                  pp=p;
           search(p->rchild,e);
        }
        else if(e<p->data)
        {
           if(p->lchild==NULL)
                return -1;
            if(p->lchild->data==e)
                if(p->lchild->lchild==NULL && p->lchild->rchild==NULL)
                    pp=p;
           search(p->lchild,e);
        }
        return 1;
    }
    void deletee(node *p,int e)//删除操作
    {
        //node *q,*s;
        if(!p->rchild && p->lchild)//右子树空,只需要重接它的左子树,即用孩子结点代替被删除的结点
        {
            node *q=new node();
            q=p;
            p=p->lchild;
            //delete q;
        }
        else if(!p->lchild && p->rchild)//左子树空,重接右子树
        {
            node *q=new node();
            q=p;
            p=p->lchild;
            //delete q;
        }
        else if(!p->lchild && !p->rchild)//左右子树皆空,为叶子结点->删除结点,并让其父节点指向该结点的指针变空
        {
            //使其父节点指向的结点变空
             if(pp->lchild->data==e)
                 pp->lchild=NULL;
             else
                 pp->rchild=NULL;
              
            node *q=new node();
            q=p;
        }
        else//左右子树皆不空
        {
            node *q=new node();node *s=new node();
            q=p;
            s=p->lchild;//转左
            
            while(s->rchild)//然后向右到尽头
            {
                q=s;
                s=s->rchild;
            }
            p->data=s->data;
            
            if(q!=p)
                q->rchild=s->lchild;
            else
                q->lchild=s->lchild;
            
            //delete s;delete q;
        }
    }
};

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        BSTtree T;
        T.creattree();
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值