#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
int val;
struct Node *lch;
struct Node *rch;
}node,*pnode;
pnode insert(pnode p,int x) //插入函数(建树)
{
if(p == NULL)
{
pnode q=(pnode)malloc(sizeof(node)); //分配空间
q->lch=q->rch=NULL; //避免野指针
q->val=x; //将数值放进去
return q;
}
else if(x < p->val) p->lch=insert(p->lch,x); //将比“头结点”小的方左边,递归
else if(x > p->val) p->rch=insert(p->rch,x); //将比“头结点”大的放右边,递归思想
return p;
}
void traverse(pnode p) //遍历函数(中序)
{
if(p==NULL) return;
if(p->lch!=NULL) traverse(p->lch); //中序访问“根节点”的左子树
printf("%d\t",p->val); //访问“根节点”
if(p->rch!=NULL) traverse(p->rch); //中序访问“根节点”的右子树
return;
}
int find(pnode p,int x) //查找函数
{
if(p == NULL) return 0; //不存在要找的值,返回空
else if(x < p->val) return find(p->lch,x); //如果比“头结点”小,递归找左边
else if(x > p->val) return find(p->rch,x); //如果比“头结点”大,递归找右边
else return 1; //找到返回1
}
pnode remove(pnode p,int x) //删除函数
{
if(p == NULL) return NULL; //不存在要删除值,返回空
else if(x < p->val) p->lch=remove(p->lch,x); //比“头结点”小,找左边
else if(x > p->val) p->rch=remove(p->rch,x); //比“头结点”大,找右边
else //要找值和头结点值相等
{
if(p->lch == NULL) { //第一种情况,要删除节点没有左孩子 将p的右孩子挂在p位置,返回q
pnode q=p->rch; //将q节点赋值为p的右孩子,
free(p);
return q;
}
else if(p->lch->rch == NULL) { //p的左孩子没有右孩子,将p的有孩子挂在p的左孩子的右孩子位置。
pnode q=p->lch; //保存p的左孩子
q->rch=p->rch; //将p的左孩子挂在p位置
free(p);
return q; //返回q
}
else { //p的左孩子有右孩子
pnode q,r;
for(q=p->lch;q->rch->rch != NULL;q=q->rch) ; //找到p的左孩子的最大数的位置。 因为左孩子的最大数位置的数比p的左孩子大,比p的有孩子小
r=q->rch; //记录最大数的位置
q->rch=q->rch->lch; //将q的左孩子挂在q位置
r->lch=p->lch; //将r挂在p位置
r->rch=p->rch;
free(p);
return r;
}
}
return p; //返回“根”节点
}
int main()
{
int x;
pnode root=NULL;
while(scanf("%d",&x) && x)
root = insert(root,x);
traverse(root);
printf("\n");
while(scanf("%d",&x) && x)
printf("%d\n",find(root,x));
while(scanf("%d",&x) && x)
root=remove(root,x);
traverse(root);
printf("\n");
while(scanf("%d",&x) && x)
printf("%d\n",find(root,x));
return 0;
}