二叉排序树删除添加etc
对于二次排序树,添加是在原树上的添加简单,
删除,传统是对几种情况的分析,
question:
根据输入的int数组建立一棵二叉排序树,然后根据指令进行相应的操作。指令只有两种Insert x, Delete x。不考虑空树的情况。
Insert x 指令需要你将x插入到建好的二叉排序树中(允许存在相同元素)。
Delete x 指令需要你将值为x的结点删除(只删除一个,而且不保证x一定在二叉排序树中)。
Input Description:
第一行为测试数据的组数n, 下面有n组测试数据。对于每组测试数据,第一行为用空格隔开的int数列,数量不超过1000,你需要用这个数据初始化一棵排序二叉树,下面一行为指令数m, 接下来的m行为m个指令。格式按照题目描述。数据均为int型。
Output Description:
输出一共有n行,对应每组测试数据,在所有的指令都执行完后,把当前的排序二叉树中序输出,元素之间用空格隔开。
eg:
Sample Input
1
1 3 5 2
2
Insert 4
Delete 5
Sample Output
1 2 3 4
#include
#include
#include
typedef struct Tree{
int val;
struct Tree *left,*right;
}Tree,*Node;
void Creat(Node *a,int e){//创建
if((*a)==NULL){
(*a)=(Node)malloc(sizeof(Tree));
(*a)->left=NULL;
(*a)->right=NULL;
(*a)->val=e;
return ;
}
if((*a)->val>e){
Creat(&((*a)->left),e);
}
else{
Creat(&((*a)->right),e);
}
}
void Delete(Node *a,int e){//删除节点
if((*a)==NULL){
return;
}
if((*a)->val==e){//如果相等的时候
if(!((*a)->left)){//当左为空的时候不能直接用下面的
(*a)=(*a)->right;
return;
}
Node l=(*a)->right;//先保存当前节点的右子树,
(*a)->val=(*a)->left->val;//把当前节点的指改成左儿子的权值
(*a)=(*a)->left;//好像与上一步的权值想矛盾,上一步应该不用写
Node t=(*a);//保持新覆盖的节点的地址
while(t->right!=NULL){//找到新覆盖节点的最右子树
t=t->right;
}
t->right=l;//把要删除的节点的右子树的值,插入到新覆盖节点的最右子树上
return;
}
if((*a)->val>e){
Delete(&((*a)->left),e);
}
else{
Delete(&((*a)->right),e);
}
}
void mid(Node a){//中序输出
if(a==NULL){
return;
}
else{
mid(a->left);
printf("%d ",a->val);
mid(a->right);
}
}
int main(){
Node T=NULL;
int n;
char C=NULL;
scanf("%d",&n);//n为要执行的操作次数
while(n--){
while(C!='\n'){//这个很巧妙,因为没告诉结束的标识,直接输入1 2 3 4所以以一个Enter为结束,以前直接想的是字符串转数字,麻烦,此方法优
int t;
scanf("%d",&t);
Creat(&T,t);
C=getchar();
}
int m;
scanf("%d",&m);//对操作的次数执行输入
while(m--){//输入Insert插入 输入Delete是删除
char S[10];
scanf("%s",S);
if(strcmp(S,"Insert")==0){
int e;
scanf("%d",&e);
Creat(&T,e);
}
else if(strcmp(S,"Delete")==0){
int e;
scanf("%d",&e);
Delete(&T,e);
}
}
mid(T);
}
}