二叉排序树

1.二叉排序树的定义
  二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree)。其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树:
①若它的左子树非空,则左子树上所有结点的值均小于根结点的值;
②若它的右子树非空,则右子树上所有结点的值均大于根结点的值;
③左、右子树本身又各是一棵二叉排序树。

2.二叉排序树的性质
   按中序遍历二叉排序树,所得到的中序遍历序列是一个递增有序序列。

3.二叉排序树的插入
   在二叉排序树中插入新结点,要保证插入后的二叉树仍符合二叉排序树的定义。   
   插入过程:
   若二叉排序树为空,则待插入结点*S作为根结点插入到空树中;   

   当非空时,将待插结点关键字S->key和树根关键字t->key进行比较,若s->key = t->key,则无须插入,若s->key< t->key,则插入到根的左子树中,若s->key> t->key,则插入到根的右子树中。而子树中的插入过程和在树中的插入过程相同,如此进行下去,直到把结点*s作为一个新的树叶插入到二叉排序树中,或者直到发现树已有相同关键字的结点为止。

//插入
int InsertBST(BiTree *T,int key)
{
	BiTree p,s;
	if(!SearchBST(*T,key,NULL,&p)) //查找不成功,可以插入
	{
		//s=(BiTree)malloc(sizeof(sizeof(BiTNode)));
		s=(BiTree)malloc(sizeof(BiTNode));
		s->data=key;
		s->lchild=NULL;
		s->rchild=NULL;
		//查找不成功,指针p指向查找路径上访问的最后一个节点,返回FALSE
		if(!p)//p为空,查找的为一颗空树
			*T=s; //插入s为根节点
		else if(key<p->data)
			p->lchild = s;
		else
			p->rchild =s;
		return true;
	}
	else
		return false;


4.二叉排序树的查找
   假定二叉排序树的根结点指针为 root ,给定的关键字值为 K ,则查找算法可描述为:
  ① 置初值: q = root ;
  ② 如果 K = q -> key ,则查找成功,算法结束;
  ③ 否则,如果 K < q -> key ,而且 q 的左子树非空,则将 q 的左子树根送 q ,转步骤②;否则,查找失败,结束算法;
  ④ 否则,如果 K > q -> key ,而且 q 的右子树非空,则将 q 的右子树根送 q ,转步骤②;否则,查找失败,算法结束。

/*
功能:二叉树的查找
key为要查找关键字
f指向T的双亲,当T为根节点时,f的初始值为NULL,它在递归时有用
查找成功,指针p指向该数据元素节点,返回TRUE
查找不成功,指针p指向查找路径上访问的最后一个节点,返回FALSE
*/
int SearchBST(BiTree T,int key,BiTree f,BiTree *p)
{
	if(!T) //T为空,或者查找不成功
	{
		*p=f;
		return false;
	}
	else if(key==T->data)
	{
		*p=T;
		return  true;
	}
	else if(key<T->data)
		return SearchBST(T->lchild,key,T,p);
	else if(key>T->data)
		return SearchBST(T->rchild,key,T,p);
}



5.二叉排序树的删除

int 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;//s指向*p的左孩子
		while(s->rchild) //然后向右到尽头(找待删除节点的前驱)
		{
			q=s;
			s=s->rchild;
		}
		(*p)->data = s->data; //s指向被删除节点的直接前驱
		if(q!=*p)  //重接q的右子树
			q->rchild = s->lchild; 
		else
			q->lchild =s->lchild; //重接q的左子树
		free(s);
	}
	return true;
}

int 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);
	}
}

树结构:

typedef struct BiTNode
{
int data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

测试:

int main()
{
	int i;
	int a[10]={62,88,58,47,35,73,51,99,37,93};
	BiTree T=NULL;
	//二叉排序树的构建
	for(i=0;i<10;++i)
		InsertBST(&T,a[i]);
	//查找
	BiTree p;
	if(SearchBST(T,93,NULL,&p))
		printf("已经找到关键字key=%d\n",p->data);
	else
		printf("没有找到\n");
	DeleteBST(&T,93);
	DeleteBST(&T,47);

	if(SearchBST(T,93,NULL,&p))
		printf("已经找到关键字key=%d\n",p->data);
	else
		printf("没有找到\n");
	printf("%d\n",sizeof(7));
	getchar();
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值