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;
}