查找树-------二叉排序树

#include <stdio.h>
#include<stdlib.h>

#define  Ok 1
#define  Error 0
#define max 20
#define Status int 
typedef struct Btree{
	Btree *lchild;
	Btree *rchild;
	int   data;
}Btree,*Bitree; //二叉排序树的结构体,和普通二叉树节点的结构一样
Btree *creattree(Bitree &b)//创建一个二叉树(普通的二叉树递归创建)
{
	int ch1;
	scanf("%d",&ch1);
	if(ch1==0)
		b=NULL;
	else
	{
		b=(Btree*)malloc(sizeof(Btree));
		if(!b)  exit(1);
		b->data=ch1;
		printf("请输入%d的左节点",b->data);
		b->lchild=creattree(b->lchild);
		printf("请输入%d的右节点",b->data);
		b->rchild=creattree(b->rchild);
	}
	return b;
}
bool  EQ(int i,int j)
{
   if(i==j)
	   return 1;
   else 
	   return 0;
}
bool LT(int i,int j)
{
	if(i<j)
		return 1;
	else 
		return 0;
}
Status SearchBST(Bitree t,int key,Bitree f,Bitree &p)//二叉查找树入口
{
	if(!t) {p=f; return false; } //如果是一颗空树的话直接返回0
	else if(EQ(key,t->data))   {p=t;  return true;}//如果找到对应的记录的话,把找到的节点赋给p,返回1
	else if(LT(key,t->data))   return SearchBST(t->lchild,key,t,p);//如果在左子树的话递归到左子树查询
	else  return SearchBST(t->rchild,key,t,p);//如果在右子树的话递归到右子树查询
}
Status InsertBST(Bitree &t,int e)//向二叉排序树中插入节点
{
	Bitree p,s;
	if(!SearchBST(t,e,NULL,p))//先查找,如果没有这个记录再插入这个记录
	{
		s=(Bitree)malloc(sizeof(Btree));
		s->data=e;  s->lchild=s->rchild=NULL;//定义一个要插入的节点
		if(!p)   t=s; //如果是一个空树的话,让这个新节点作为整棵树的根节点
		else if(LT(s->data,p->data))   p->lchild=s;//因为返回的p是整棵树的叶子节点,所以插入的节点只需比较与p的大小,
		else   p->rchild=s;  //直接插入p的左孩子或是右孩子节点
		return true ;
	}
	else return  false;
}
Status Delete(Bitree &p)//在二叉排序树中删除节点
{
	Bitree q,s;
	//q=(Btree*)malloc(sizeof(Btree));
	//s=(Btree*)malloc(sizeof(Btree));
	if(!p->rchild)//如果要删除的这个节点没有右子树的话,直接让p变成p的lchild即可
	{
		q=p; p=p->lchild;  free(q);
	}
	else if(!p->lchild) //如果要删除的这个节点没有左子树的话,直接让p变成p的rchild即可
	{
		q=p; p=p->rchild;  free(q);
	}
	else//如果要删除的这个节点左右子树都存在的话
	{
		q=p; s=p->lchild;
		while(s->rchild)  {q=s;s=s->rchild;}//s是要删除的p节点的左孩子节点的右孩子节点里面最右面的一个,p是s的父节点
		p->data=s->data;  //把s里的数据赋值给P
		q->rchild=s->lchild;//把最右面的左子树给倒数第二个的右子树
		free(s);//把s删除
	}
	return Ok;
}
Status DeleteBST(Bitree &t,int key)//删除函数的入口
{
	if(!t)  return false;
	else
	{
		if(EQ(key,t->data))  {return Delete(t);}//如果找到了就调用Delete函数
		else if(LT(key,t->data))   return  DeleteBST(t->lchild,key);//递归查找
		else return DeleteBST(t->lchild,key);
	}
}
Status Showtree(Bitree t)
{
	if(t)
	{
		if(Showtree(t->lchild))
		{
			printf("%d\n",t->data);
			if(Showtree(t->rchild))
				return Ok;
		}
	}
	else return Ok;
}
void main()
{
	Bitree t;
	int e;
	printf("请输入树的根节点");
	creattree(t);
	printf("请输入您要查询的数字如果没有将插入图中");
	scanf("%d",&e);
	InsertBST(t,e);
    printf("该树的中序序列为");
	Showtree(t);
	printf("请输入要删除的节点:");
	scanf("%d",&e);
	DeleteBST(t,e);
	printf("该树的中序序列为:");
	Showtree(t);
	getchar();
	getchar();
}
//算法分析:1.二叉排序树要求:(1)它的左子树不为空,那么所有节点的值均小于它很节点的值(2)它的右子树不为空,那么所有节点的值均大于它很节点的值
//(3)它的左右子树也符合
 //2.在删除节点的算法中,处理方法有两种,一种是如上程序所写,将左子树最右边的一个节点值进行互换,删除那最右边的节点,还有一种就是将P节点直接删去
//将p的父节点和p的左孩子节点连接,再将P的有孩子节点直接连在p的左孩子节点的最右端,也就是s节点的右孩子节点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值