搜索二叉树的相关操作

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


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值