二叉搜索树的理解

二叉搜索树:任意两个节点的关键字值不同;若左子树、右子树不空,左子树键值<根节点键值< 右节点键值;左右子树也分别是 二叉搜索树。

性质:以中序遍历二叉 搜索树,那么将会得到一个递增的序列。

关于二叉搜索树的删除:容易理解,二叉搜索树的任意一颗子树的最大元素和最小元素所在的节点的度<=1,既然二叉搜索树以中序遍历时是一个递增的序列,那么删除二叉搜索树的一个节点,相当于在中序遍历序列中删除此节点,那么该节点可以用直接后继(或者直接前继)来替换。 

删除的节点可能有两颗非空子树, 也可能最多只有一颗非空子树。如果此节点有两颗非空子树,那么该节点将被其中序遍历的序列的直接后继替换, 直接后继必定是该节点右子树中的最小元素,既然是最小元素,那么其节点的度不会大于1,删除此节点就会 相对容易,这也转换 成删除一个最多有一颗非空子树的 节点。删除 最多有一颗非空子树的节点,只要 用其左子树来替换或者右子树替换即可,如果左子树非空就用左子树替换,否则用右子树替换,这样如果子树均空的情况也被包含进去。

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

typedef struct entry{
	int Key;
	int Data;
}Entry;
typedef struct bstnode{
	Entry Element;
	struct bstnode *LChild,*RChlid;
}BSTNode,*BSTree;

BSTree RecSearchBST(BSTree T,int k)//递归搜索 ,如果搜索到把节点的指针返回 
{
	if(!T)
		return NULL;
	if(T->Element.Key==k)
		return T;//当前的节点的键值匹配成功
	else if(T->Element.Key>k) 
		return RecSearchBST(T->LChild,k);//k比较小,向左孩子方向搜索
	else 
		return RecSearchBST(T->RChlid,k) ;//k比较大,向右孩子方向搜索 
}

int InsertBST(BSTree &T,Entry e)
{
	//int key=e.Key;
	BSTree temp=T,l;
	
	while(temp)
	{
		l=temp;//l暂存未变化的temp 
		if(temp->Element.Key<e.Key)
			temp=temp->RChlid;
		else if(temp->Element.Key>e.Key)	
			temp=temp->LChild;
		else
		{
			printf("重复\n");
			return 0;
				
		}
		
	}
	//至此temp指向一个NULL
	temp=(BSTNode*)malloc(sizeof(BSTNode));
	temp->LChild=temp->RChlid=NULL;
	temp->Element=e;
	if(!T)//如果T是空的 
		T=temp;
	else if(l->Element.Key<e.Key)//下面两种情况是T非空 
		l->RChlid=temp;
	else
		l->LChild=temp;
	return 1;
	
	
}

int DeleteBST(BSTree &T,int k) 
{
	BSTree p=T,q,s,r,c;//p指向待删除的节点,q是p的双亲节点;s,r是在有两颗非空子树的情况下的暂时变量 ;c是最终进行删除操作时的用到的。 
	while(p&&p->Element.Key!=k)
	{
		q=p;//q是p的双亲节点 
		if(k<p->Element.Key)
			p=p->LChild;
		else
			p=p->RChlid;
	}
	if(!p)
	{
		printf("不存在");
		return 0;
	}
	if(p->LChild&&p->RChlid)//如果有两颗非空子树 
	{
		s=p->RChlid;//方便找到节点的直接后继 
		r=p;// 可能s就是其的直接后继,然后将r作为s的父节点 
		while(s->LChild) 
		{
			r=s;
			s=s->LChild;//直到找到最小值 
		}
		p->Element=s->Element;
		p=s;q=r;//相当于转换成了最多有一个非空子树的待删除节点 
	}
	//上面的处理可以将有两颗非空子树的节点转换为删除最多有一颗非空子树的节点 
	
	if(p->LChild)
		c=p->LChild;
	else
		c=p->RChlid;
	
	//接下来就是准备删除操作了
	if(p==T) 
		T=c;//判断是否为根节点,此步也可以判断q是否为NULL,这需要在定义q时初始化NULL。
	else if(p==q->LChild)//接下来就是判断,p是q的左子树还是右子树了 
		q->LChild=c;
	else
		q->RChlid=c;
		
	free(p);
	return 1;
}
int main()
{
	BSTree T=NULL;
	Entry a;
	a.Data=0;a.Key=1;
	InsertBST(T,a);
    InsertBST(T,a);
	DeleteBST(T,1);
	system("pause");
	return 0;
	
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值