sdut 暑假结训赛 巨斧砍大树

巨斧砍大树
Time Limit: 1000 Memory Limit: 65536
Description
阿福最近练就了一个新的招式:巨斧砍大树。这个招式可以砍掉一颗二叉搜索树的某个子树。现在,阿福面前有一颗 n 个结点的二叉搜索树,他要使用 m 次招式,于是他想询问你每次使用「巨斧砍大树」后二叉搜索树会被砍成什么样子。


二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。


Input
第 1 行输入 2 个整数 n, m (1 <= n, m <= 10)。表示二叉搜索树的结点个数和招式使用次数。


第 2 行输入 n 个空格隔开的整数 v (1 <= v <= 10),表示二叉搜索树是以此序列顺序插入生成的二叉树(保证互不相同)。


接下来输入 m 行,每行一个整数 w (1 <= w <= 10),表示阿福要砍掉结点上数值为 w 的子树(保证 w 是初始二叉树上存在的数值)。


Output
对于每次砍树,如果成功砍掉子树,则先输出一行 "Cut x",其中 x 为被砍掉子树的根节点上的数值。如果要砍掉的结点在之前已被砍掉,则输出一行 "Already cut x",x 的含义同上。


随后输出一行,表示此次砍树结束后当前二叉树的中序遍历结果,以空格分隔(行末没有多余空格,如果整颗二叉树已为空,则输出一行空行)。


Sample Input
5 5
1 3 2 4 5
5
2
3
4
1


Sample Output
Cut 5
1 2 3 4
Cut 2
1 3 4
Cut 3
1
Already cut 4
1

Cut 1

代码:

#include <stdio.h>
#include <stdlib.h>
/*
1、本题思想其实很简单,只需要建立一个排序二叉树,然后查找数据元素
所在二叉树的位置,找到以后将其根节点变为空,同时将其左右子树变为空
2、本题输出遍历后的数据元素时,因为有具体要求(最后一个元素后面无空格)
所以我们可以使用一个数组来保存元素*/
typedef int element ;
typedef struct node
{
    element data;
    struct node *lchild,*rchild;
} Bnode,*BiTree;
int a[100];
int k;int g;
//建立排序二叉树
BiTree creat(BiTree root,int k)
{
    if(!root)
    {
        root=(BiTree )malloc(sizeof(Bnode));
        root->data=k;
        root->lchild=NULL;
        root->rchild=NULL;
    }
    else
    {
        if(k>root->data)
            root->rchild=creat(root->rchild,k);
        if(k<root->data)
            root->lchild=creat(root->lchild,k);
    }
    return root;
}
//在二叉树中查找到具体元素,并将其和左右子树变为空
BiTree find(BiTree root,int k)
{
    if(root)
    {
        if(root->data==k)  //找到数据元素,并将标记记为1;
        {
            root->lchild=NULL;
            root->rchild=NULL;
            root=NULL;
            g=1;
        }
        else  //左右寻找数据元素
        {
            if(k<root->data)
                root->lchild=find(root->lchild,k);
            if(k>root->data)
                root->rchild=find(root->rchild,k);
        }
    }
    else   //找不到数据元素,标记为0;
    {
        g=0;
    }
    return root;
}
void midprint(BiTree root)  //输出中序遍历结果
{
    if(root)
    {
        midprint(root->lchild);
        a[k++]=root->data;
        midprint(root->rchild);
    }
}
int main()
{
    BiTree root=NULL;
    int n,m;
    int i;
    int t;int p;
    scanf("%d %d",&n,&m);
    for(i=0; i<n; i++)
    {
        scanf("%d",&t);
        root=creat(root,t);
    }
    while(m--)
    {
        k=0;
        scanf("%d",&p);
        root=find(root,p);
        if(g==0)  //当标记为0时,说明以此元素为根节点的值为空,即该元素已被砍掉
            printf("Already cut %d\n",p);
        if(g==1)   //当标记为1时,说明该元素还为被删除
        {
            printf("Cut %d\n",p);
            midprint(root);
            if(k==0)  //k为0,说明整个二叉树为空,无数据元素
                printf("\n");
            else  //k不为0,输出数组元素
            {
                for(i=0;i<k-1;i++)
                    printf("%d ",a[i]);
                printf("%d\n",a[k-1]);


            }
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值