二叉排序树(概念,查找,插入,删除)

查找基本概念

查找表:由同一类型的数据元素构成的集合。对查找表的常用操作:查询元素是否存在、查询元素属性、插入一个数据元素、删除一个数据元素。

查找:也叫检索,是根据给定的某个值,在表中确定一个关键字等于给定值的数据元素。

关键字:可以标识一个数据元素的某个数据项。

主关键字:可以唯一地识别一个数据元素的关键字。

静态查找表:只进行查询某元素在表中与否或检索某元素的各种属性操作的表。

动态查找表:查找时同时进行插入表中无的元素或删除表中有的某元素的表。

二叉排序树

定义:二叉排序树(Binary Sort Tree)或者是一棵空树;或者是具有下列性质的二叉树:

1)若左子树不空,则左子树上所有结点的值均小于根结点的值;若右子树不空,则右子树上所有结点的值均大于等于根结点的值。2)左右子树也都是二叉排序树。

二叉排序树查找过程:若二叉排树为空,则查找失败,否则,先拿根结点值与待查值进行比较,若相等,则查找成功,若根结点值大于待查值,则进入左子树重复此步骤,否则,进入右子树重复此步骤,若在查找过程中遇到二叉排序树的叶子结点时,还没有找到待找结点,则查找不成功。

 二叉树的二叉链表结点结构定义 

typedef  struct BiTNode	/* 结点结构 */
{
	int data;	/* 结点数据 */
	struct BiTNode *lchild, *rchild;	/* 左右孩子指针 */
} BiTNode, *BiTree;

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

/*  当二叉排序树T中不存在关键字等于key的数据元素时, 
 插入key并返回true,否则返回false */
bool InsertBST(BiTree *T, int key)
{
	BiTree p,s;//中间变量
	if (!SearchBST(*T,key,NULL,&p))//查找不成功
	{
		s=(BiTree)malloc(sizeof(BiTNode));
		s->data=key;
		s->lchild=s->rchild=NULL;
		if (!p)//树为空,插入新的根结点
		{
			*T=s;
		}
		else if (key<p->data)
		{
			p->lchild=s;//插入左孩子
		}
		else
			p->rchild=s;//插入右孩子
		return true;
	}
	return false;
}

二叉排序树删除操作

bool DeleteBST(BiTree *T, int key)
{
	if (!*T)//不存在关键字等于key的数据元素
	  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);

}
/* 从二叉排序树中删除结点p,并重接它的左或右子树*/
bool 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的右子树
			q->rchild=s->lchild;
		}
		else
		{
			//重建q的左子树
			q->lchild=s->lchild;
		}
		free(s);
	}
	return true;
}
转载请注明出处: http://blog.csdn.net/lsh_2013/article/details/45601089



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值