二叉排序树的检索,插入和删除

要求:
1、用链式存储实现字典结构。
2、对构造好的二叉排序树进行中根序遍历
3、对构造好的二叉排序树进行数据的和检索

#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
struct BinSearchTree		//二叉排序树结点定义
{
	DataType data;		//数据域
	struct BinSearchTree*rchild;		//右子树指针
	struct BinSearchTree*lchild;		//左子树指针
};
typedef struct BinSearchTree *BSTree;		//二叉排序树指针

//函数功能:建立二叉排序树
//输入参数:无
//返回值:二叉树的根
BSTree Creat()
{
	BSTree b;			//定义二叉树
	DataType x;
	scanf("%d", &x);	//输入结点
	if (x == -1)
		b = NULL;
	else
	{
		b = (BSTree)malloc(sizeof(struct BinSearchTree));		//申请空间
		b->data = x;			//数据域赋值
		b->lchild = Creat();		//创建左结点
		b->rchild = Creat();		//创建右结点
	}
	return b;			//返回结点
}
//函数功能:检索二叉排序树
//输入参数:排序树的根,需要检索的元素
//返回值:成功返回零若不成功,返回其父结点的位置信息

BSTree SearchFindMin(BSTree T)
{
	if(T == NULL)
        return NULL;
    if(T->lchild == NULL)
        return T;
    else return SearchFindMin(T->lchild);
}
//函数功能:在二叉排序树中插入某结点
//输入参数:排序树的根,需要插入的元素
//返回值:成功返回1,不成功返回0

BSTree SearchFind(BSTree T,DataType key)  //左子树最大值
{
	if(T == NULL)
        return NULL;
    if(T->data == key)
        {
            printf("查找成功!\n");
            return T;
        }
    else if(T->data > key)
        return SearchFind(T->lchild,key);
    else
        return SearchFind(T->rchild,key);
}

BSTree SearchFindMax(BSTree T)     //右子树最小值
{
    if(T == NULL)
        return NULL;
    if(T->rchild == NULL)
        return T;
    else return SearchFindMax(T->rchild);
}

//在给定的BST中插入结点,其数据域为element
void Insert(BSTree T,int x)
{
    //这里创建一个要插入的节点
    BSTree pInsert = (BSTree)malloc(sizeof(struct BinSearchTree));
    pInsert->data = x;
    pInsert->lchild = NULL;
    pInsert->rchild = NULL;
    if (T == NULL)
        T = pInsert;
    if (T->lchild == NULL && x < T->data)
        T->lchild = pInsert;
    if (T->rchild == NULL && x > T->data)
        T->rchild = pInsert;
    //递归实现
    if (x < T->data)
        Insert(T->lchild, x);
    if (x > T->data)
        Insert(T->rchild, x);
    return;
}

//函数功能:删除二叉排序树中某个元素
//输入参数:二叉排序树的根,要删除的元素key
//返回值:无
void DeleTree(BSTree T,DataType key)
{
	BSTree p, q;
	p = T;
	DataType temp;
	while( p != NULL && key != p->data )
    {
		q = p;
		if( key < p->data )
			p = p->lchild ;
		else
			p = p->rchild ;
	}
	if( NULL == p )
		printf("无此元素!\n");
	else
	{
		//情况1:结点p的双亲结点为q,且p为叶子结点,则直接将其删除。
        if( NULL == p->lchild && NULL == p->rchild )
        {
			if( p == q->lchild )
				q->lchild = NULL;
			if( p == q->rchild )
				q->rchild = NULL;
			free(p);
			p = NULL;
		}
		//情况2:结点p的双亲结点为q,且p只有左子树或只有右子树,则可将p的左子树或右子树直接改为其双亲结点q的左子树或右子树。
		else if( (NULL == p->rchild && NULL != p->lchild) )
		{	//p只有左子树
			if( p == q->lchild )
				q->lchild = p->lchild ;
			else if( p == q->rchild )
				q->rchild = p->lchild ;
			free(p);
			p = NULL;
		}
		else if( NULL == p->lchild && NULL != p->rchild )
		 {		//p只有右子树
			if( p == q->lchild )
				q->lchild = p->rchild ;
			if( p == q->rchild )
				q->rchild = p->rchild ;
			free(p);
			p = NULL;
		}
		//情况3:结点p的双亲结点为q,且p既有左子树又有右子树。本代码使用直接前驱(也可以直接后继)
		else
        {
				BSTree s, sParent;
				sParent = p;
				s = sParent->lchild ;
				while( NULL != s->rchild )
                {	//找到p的直接前驱
					sParent = s;
					s = s->rchild ;
				}
				temp = s->data ;
				DeleTree( T, temp );
				p->data = temp;
		}
	}

}

void Iorder(BSTree T)
{
	if(T == NULL)		//如果为空树则返回
		return;
	Iorder(T->lchild);
	printf("%d ",T->data);//访问结点
	Iorder(T->rchild);
 }

 void BSTdestory(BSTree T)    //销毁二叉树
{
    if(T != NULL)
    {
        BSTdestory(T->lchild);
        BSTdestory(T->rchild);
        free(T);
    }
}

 void main()
 {
 	BSTree b;
 	BSTree p;
 	DataType x;
 	printf("请输入(整型)二叉排序树的先序序列:\n");
 	b = Creat();
 	printf("\n二叉排序树的中序遍历为:\n");
 	Iorder(b);
 	printf("\n");
 	printf("\n请输入要查找的元素(成功返回该关键词并返回其指针,不成功则返回0):");
	scanf("%d",&x);
	printf("%d\n",SearchFind(b,x)) ;
 	printf("\n请输入要插入的元素:");
	scanf("%d",&x);
    Insert(b,x);
	printf("插入成功后的中序遍历为:\n");
 	Iorder(b);
 	printf("\n");
 	printf("\n请输入要删除的元素:");
 	scanf("%d",&x);
 	DeleTree(b,x);
 	printf("删除成功后的中序遍历:\n");
 	Iorder(b);
 	printf("\n");
 	BSTdestory(b);
 }

本人还比较菜,代码我就懒得分头文件了,,,感兴趣的读者自己弄一下。。。
欢迎互相学习互相交流!

以下是代码运行结果的截图 这是代码的运行截图,欢迎互相学习!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值