二叉排序树的查找、插入和删除

二叉排序树(Binary Sort Tree)又称为二叉查找树,它或者是一棵空树,或者是具有下列性质的二叉树:

若它的左子树不为空,则左子树上所有结点的值均小于它的根结构的值;

若它的右子树不为空,则右子树上所有结点的值均大于它的根结构的值;

它的左、右子树也分别为二叉排序树(递归)。

//二叉排序树

//二叉排序树的查找操作
//二叉树的二叉链表结点结构定义
typedef struct BiTNode
{
	int data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

//递归查找二叉排序树T中是否存在key
//指针f指向T的双亲,其初始值为NULL
//若查找成功,则指针p指向该数据元素结点,并返回TRUE
//否则指针p指向查找路径上访问的最后一个结点,并返回FALSE
Status SearchBST(BiTree T,int key,BiTree f,BiTree *p)
{
	if(!T)
	{
		*p=f;
		return FALSE;
	}
	else if(key==T->data) //查找成功
	{
		*p=T;
		return TRUE;
	}
	else if(key<T->data)
	{
		return SearchBST(lchild,key,f,p);//在左子树中继续查找
	}
	else
	{
		return SearchBST(rchild,key,f,p);//在右子树中继续查找
	}
}

//二叉排序树的插入操作
//当二叉排序树T中不存在关键字等于key的数据元素时,
//插入key并返回TRUE,否则返回FALSE
Status InsertBST(BiTree *T,int key)
{
	BiTree p,s;
	if(!SearchBST(*T,key,NULL,&p))//查找失败,即T中不存在关键字key
	{
		s=(BiTree)malloc(sizeof(BiTNode));
		s->data=key;
		s->lchild=s->rchild=NULL;
		
		if(!p) //查找不到key
		{
			*T=s; //插入s为新的根结点
		}
		else if(key<p->data)
		{
			p->lchild=s;//插入s为左孩子
		}
		else
		{
			p->rchild=s;//插入s为右孩子
		}
		return TRUE;
	}
	else
	{
		return FALSE; //树中已经包含关键字相同的结点,不再插入
	}
}
//二叉排序树的删除操作
Status DeleteBST(BiTree *T,int key)
{
	if(!*T)
	{
		return FALSE;
	}
	else
	{
		if(key==(*T)->data)
		{
			return Delete(T);
		}
		else if(key<(*T)->data)
		{
			return DeleteBST(&(*T)->lchild,key);
		}
		else
		{
			return DeleteBST(&(*T)->rchild,key);
		}
	}
}

Status Delete(BiTree *p)
{
	BiTree q,s;
	if((*p)->rchild==NULL)//右子树为空
	{
		q=*p;
		*p=(*P)->lchild;
		free(q);
	}
	else if((*p)->lchild==NULL)//左子树为空
	{
		q=*p;
		*p=(*P)->rchild;
		free(q);
	}
	//左右子树都不为空,然后在左子树中找到最大值来代替该结点,
	//或者在右子树中找到最小值来代替该结点,此处选择在左子树中查找最大值
	else
	{
		q=*p;
		s=(*p)->lchild;
		
		while(s->rchild)
		{
			q=s;
			s=s->rchild;
		}
		(*p)->data=s->data;
		if(q!=*p)
		{
			q->rchild=s->lchild;
		}
		else
		{
			q->lchild=s->lchild;//q==*p,即p和q均指向要删除的结点,s指向该结点的左子树
		}
		
		free(s);
	}
	
	return TRUE;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值