数据结构_查找_动态查找表_二叉排序树

定义:
二叉排序树(Binary Sort Tree)又称二叉查找树。 它或者是一棵空树;或者是具有下列性质的二叉树: 
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
下面代码中主要实现了二叉树的插入,删除,查找三个功能;具体的实现有注释,如果有错误或者您不理解的地方,欢迎提出来,大家共同讨论。
#include<stdio.h>
#include<malloc.h>
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
typedef int KeyType ;
typedef struct ElemType			//树的存储内容,为了简便,只存储了关键值
{
	KeyType key;//关键字
}ElemType;
typedef struct BSTNode			//二叉排序树的结构
{
	ElemType data;
	BSTNode *lchild,*rchild;
}*BSTree;
void InitBSTree(BSTree &T)	//树的初始化
{
	T=NULL;
}
int SearchBST(BSTree T,KeyType key,BSTree f,BSTree &p)
//查找关键值为key的函数,若存在这个结点,则在p中保存该结点的地址,
//若不存在这个值,则p中保存查找路径上的最后一个结点的位置,并返回0
{
	if(!T)
	{
		p=f;
		return 0;
	}
	else if(EQ(T->data.key,key))
	{
		p=T;
		return 1;
	}
	else if(LT(T->data.key,key))
		SearchBST(T->rchild,key,T,p);
	else
		SearchBST(T->lchild,key,T,p);
}
int InsertBST(BSTree &T,ElemType e)
{
	BSTree p;
	if(!SearchBST(T,e.key,NULL,p))	//首先在树中查找是存在与待插关键字相等的元素,如果存在,返回0,不存在,p中已经保存待插位置的地址
	{
		BSTree s=(BSTree)malloc(sizeof(BSTNode));
		s->data=e;
		s->lchild=s->rchild=NULL;
		if(!p)								//如果p是空树的话
			T=s;
		else if(LT(e.key,p->data.key))		//如果待插结点的值小于双亲结点的值,则插在左孩子中
			p->lchild=s;
		else								//否则插入右孩子中
			p->rchild=s;
		return 1;
	}
	else
		return 0;
}
void Delete1(BSTree & p)
//删除p这个结点,由于整个二叉排序树中序遍历是有序的,
//所以当p点结点的值删除后,p点若从子树中的结点中选取一个替换p结点,
//则这个结点要保证比不小于左子树所有结点,不大于右子树中所有结点
//因此可以选取p结点的前驱结点,就是左子树的第一个结点的,一直向右走的最后一个结点即可
{
	BSTree q;
	if(p->lchild==NULL)//如果左子树为空,只需要讲右子树的第一个结点往前提一个即可
	{
		q=p;
		p=p->rchild;
		free(q);
	}
	else if(p->rchild==NULL)
	{
		q=p;
		p=p->lchild;
		free(q);
	}
	else
	{
		BSTree s=p->lchild;
		q=p;
		while(s->rchild!=NULL)
		{
			q=s;
			s=s->rchild;
		}
		p->data=s->data;
		if(q!=p)
			q->rchild=s->rchild;
		else
			q->lchild=s->lchild;
	}

}
int DeleteBST(BSTree &T,KeyType key)
{
	if(!T)
		return 0;
	else
	{
		if(EQ(key,T->data.key))
			Delete1(T);
		else if(LT(key,T->data.key))
			DeleteBST(T->lchild,key);
		else
			DeleteBST(T->rchild,key);
		return 1;
	}
}
void InOrderTraverse(BSTree T)
{
	if(T)
	{
		InOrderTraverse(T->lchild);
		printf("%d ",T->data.key);
		InOrderTraverse(T->rchild);
	}
}
int main()
{
	BSTree T,p;
	InitBSTree(T);
	int i;
	ElemType e[6];
	e[0].key=45;
	e[1].key=24 ;
	e[2].key=53;
	e[3].key=12 ;
	e[4].key=37 ;
	e[5].key=93 ;
	for(i=0;i<6;i++)
		InsertBST(T,e[i]);
	InOrderTraverse(T);
	printf("\n");
	SearchBST(T,54,NULL,p);
	printf("%d\n",p->data.key);
	DeleteBST(T,24);
	InOrderTraverse(T);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值