/***********************************************************
* 搜索二叉树
*原理:左边的孩子比之前的头都小,右边的孩子比之前的头都大;
*思想:利用递归的思想
*遍历:利用 中序 遍历输出的是从小到大的顺序
**********************************************************/
#include<stdio.h>
#include<stdlib.h>
typedef struct Node //定义节点结构体
{
int val;
struct Node *left;
struct Node *right;
}node,*pnode;
pnode insert(pnode p,int x) //插入
{
if(p == NULL) //如果为空,说明无当前节点
{
p=(pnode)malloc(sizeof(node)); //申请空间
p->left=NULL;
p->right=NULL; //把左右孩子置为空
p->val=x; //赋值
}
else
if(x>p->val) //大于他像又指
p->right=insert(p->right,x); //p->right用于接受返回的p
else if(x<p->val)
p->left=insert(p->left,x);
return p; //返回头:他会利用递归,再把头递归回去,所以一直是头
}
int find(pnode p,int x) //查找
{
if(p==NULL) //先判断是否为空,则返回0
return 0;
else if(x>p->val)
return find(p->right,x);
else if(x<p->val) //大于他就想左查找
return find(p->left,x);
else //查到等于,返回1;
return 1;
}
pnode del(pnode p,int x) //删除 (分三种情况)
{
if(p==NULL)
return NULL;
else if(x>p->val)
p->right=del(p->right,x);
else if(x<p->val)
p->left=del(p->left,x);
else //查到等于时,分三种
if(p->left ==NULL) //p的左孩子为空,把p的右孩子直接挂给他;
{
pnode q =p->right;
free(p);
return q; //返回q,上面接收
}
else if(p->left->right==NULL) //p的左孩子的右孩子为空,把p的右孩子
{ // 挂到p的左孩子的右孩子的地方,再把p的做孩子挂到p那,释放就好
pnode q= p->left;
q->right=p->right;
free(p);
return q;
}
else //p的左孩子的右孩子的右孩子为空的情况,是把p的左孩子的右孩子
{ // (如果有左孩子的话)的左孩子挂到p的左孩子的右孩子那
pnode q; //之前先要保存,在把p的左孩子的右孩子挂到最上面;
for(q=p->left;q->right->right !=NULL ;q=q->right) ; //找到为空地方,空语句
pnode r=q->right; //保存节点
q->right=r->left; //是把p的左孩子的右孩子(如果有左孩子的话)的左孩子挂到p的左孩子的右孩子那
r->left=p->left; //把p的左孩子和右孩子挂到r的左右孩子那,指向
r->right=p->right; //
free(p);
return r;
}
return p;
}
void traverse(pnode p)
{
if(p ==NULL )
return ;
if(p->left!=NULL)
traverse(p->left);
printf("%d\t",p->val);
if(p->right !=NULL)
traverse(p->right);
}
int main()
{
int x;
pnode root=NULL;
printf("input number:\n");
while(scanf("%d",&x) && x) //遇到零就停止输入
root=insert(root,x);
printf("show the tree:\n");
traverse(root);
putchar('\n');
printf("input number which you want:\n");
while(scanf("%d",&x) && x)
printf("%d\n",find(root,x));
printf("input number which you want delete:\n");
while(scanf("%d",&x) && x)
root=del(root,x);
printf("show again:\n");
while(scanf("%d",&x) && x)
printf("%d\n",find(root,x));
return 0;
}