【数据结构-树】C语言实现二叉排序树基本操作

基本操作

定义存储结构

//定义存储结构 
typedef struct
{
	KeyType key;
	OtherInfo info;
}ElemType;
typedef struct BSNode
{
	ElemType data;
	struct BSNode *lchild,*rchild;
}BSNode,*BSTree;

插入结点

//二叉排序树插入数据
void InsertBST(BSTree *T,ElemType e)    //传入树根结点指针地址 
{
	if(*T==NULL)  //树结点指针空 
	{
		BSNode *S = (BSNode *)malloc(sizeof(BSNode));   //开辟新结点空间单元 
		S->data = e;   //传入数据元素 
		S->lchild=S->rchild=NULL;    //左右孩子指针域置空 
		*T = S;   //传递指针(地址) 
	}
	else if(e.key < (*T)->data.key) InsertBST(&(*T)->lchild,e);   //数值小于根结点,插入到左子树上 
	else InsertBST(&(*T)->rchild,e);   //否则右子树 
}

创建二叉排序树

//创建二叉排序树
void CreateTree(BSTree *T)
{
	ElemType e;
	*T = NULL;    //根节点指针置空 
	printf("请为二叉排序树输入排序树:");
	scanf("%d",&e.key);
	while(e.key !=0)
	{
		InsertBST(T,e);   //循环插入数据 
		scanf(" %d",&e.key);
	}
}

二叉排序树删除结点

//二叉排序树删除结点
void DeleteBST(BSTree *T,KeyType key)
{
	BSNode *p=*T,*q,*s,*f=NULL;    
	//p指针用于记住给定值在二叉树结点的地址,q  ,f记录给定值的双亲指针 
	while(p)   //循环找到二叉树找到等于给定值的指针 
	{
		if(p->data.key==key) break;
		f=p;
		if(p->data.key>key) p=p->lchild;    //小于根结点的数值就往左子树找 
		else p=p->rchild;   //否则往右子树找 
	}
	if(!p) return;    //找不到就结束函数调用 
	if((p->lchild)&&(p->rchild))    //找等于给定值结点,并有左右子树 
	{
		q=p;    //初始指向给定值 
		s=p->lchild;   //指向给定值左孩子    往等于给定值结点的左子树找前驱结点 
		while(s->rchild)
		{
			q=s;             //记录前驱节点的双亲结点的指针 
			s=s->rchild;     //记录前驱结点指针 
		}
		p->data = s->data;    //将前驱节点的数值替代给定值结点里的数值 
		if(q!=p) q->rchild = s->lchild;    //前驱结点的双亲并不是给定值指针  双亲的右孩子指针域指向前驱结点的左孩子 
		else q->lchild = s->lchild;       //前驱结点的双亲是给定值指针   双亲的右孩子指针域(等于给定值结点)指向前驱结点的左孩子
		free(s);   //释放结点空间 
		return;    //结束调用 
	}
	else if(!p->rchild)    //没有右子树 
	{
		q=p;
		p = p->lchild;
	}
	else     //没有左子树 
	{
		q=p;
		p=p->rchild;
	}
	if(!f) *T=p;    //等于给定值结点没有双亲结点时,它的左子孩子代替它的位置 
	else if(q==f->lchild) f->lchild = p;     //等于给定值结点的指针等于双亲的左孩子时,双亲左孩子指针指向它的后继结点 
	else f->rchild=p;     //双亲右孩子指针指向它后继结点 
	free(q);   //释放 等于给定值结点
}

中序遍历

//中序遍历
void InOrder(BSTree T)
{
	if(T)
	{
		InOrder(T->lchild);      //递归输出 L 
		printf("%d ",T->data.key);     //输出根 D 
		InOrder(T->rchild);      //递归输出 R 
	}
}

测试代码整合

#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;
typedef int KeyType;
typedef int OtherInfo;
//定义存储结构 
typedef struct
{
	KeyType key;
	OtherInfo info;
}ElemType;
typedef struct BSNode
{
	ElemType data;
	struct BSNode *lchild,*rchild;
}BSNode,*BSTree;

//二叉排序树插入数据
void InsertBST(BSTree *T,ElemType e)    //传入树根结点指针地址 
{
	if(!(*T))  //树结点指针空 
	{
		BSNode *S = (BSNode *)malloc(sizeof(BSNode));   //开辟新结点空间单元 
		S->data = e;   //传入数据元素 
		S->lchild=S->rchild=NULL;    //左右孩子指针域置空 
		*T = S;   //传递指针(地址) 
	}
	else if(e.key < (*T)->data.key) InsertBST(&(*T)->lchild,e);   //数值小于根结点,插入到左子树上 
	else InsertBST(&(*T)->rchild,e);   //否则右子树 
}

//创建二叉排序树
void CreateTree(BSTree *T)
{
	ElemType e;
	*T = NULL;    //根节点指针置空 
	printf("请为二叉排序树输入排序树:");
	scanf("%d",&e.key);
	while(e.key !=0)
	{
		InsertBST(T,e);   //循环插入数据 
		scanf(" %d",&e.key);
	}
}

//二叉排序树删除结点
void DeleteBST(BSTree *T,KeyType key)
{
	BSNode *p=*T,*q,*s,*f=NULL;    
	//p指针用于记住给定值在二叉树结点的地址,q  ,f记录给定值的双亲指针 
	while(p)   //循环找到二叉树找到等于给定值的指针 
	{
		if(p->data.key==key) break;
		f=p;
		if(p->data.key>key) p=p->lchild;    //小于根结点的数值就往左子树找 
		else p=p->rchild;   //否则往右子树找 
	}
	if(!p) return;    //找不到就结束函数调用 
	if((p->lchild)&&(p->rchild))    //找等于给定值结点,并有左右子树 
	{
		q=p;    //初始指向给定值 
		s=p->lchild;   //指向给定值左孩子    往等于给定值结点的左子树找前驱结点 
		while(s->rchild)
		{
			q=s;             //记录前驱节点的双亲结点的指针 
			s=s->rchild;     //记录前驱结点指针 
		}
		p->data = s->data;    //将前驱节点的数值替代给定值结点里的数值 
		if(q!=p) q->rchild = s->lchild;    //前驱结点的双亲并不是给定值指针  双亲的右孩子指针域指向前驱结点的左孩子 
		else q->lchild = s->lchild;       //前驱结点的双亲是给定值指针   双亲的右孩子指针域(等于给定值结点)指向前驱结点的左孩子
		free(s);   //释放结点空间 
		return;    //结束调用 
	}
	else if(!p->rchild)    //没有右子树 
	{
		q=p;
		p = p->lchild;
	}
	else     //没有左子树 
	{
		q=p;
		p=p->rchild;
	}
	if(!f) *T=p;    //等于给定值结点没有双亲结点时,它的左子孩子代替它的位置 
	else if(q==f->lchild) f->lchild = p;     //等于给定值结点的指针等于双亲的左孩子时,双亲左孩子指针指向它的后继结点 
	else f->rchild=p;     //双亲右孩子指针指向它后继结点 
	free(q);   //释放 等于给定值结点
}

//中序遍历
void InOrder(BSTree T)
{
	if(T)
	{
		InOrder(T->lchild);      //递归输出 L 
		printf("%d ",T->data.key);     //输出根 D 
		InOrder(T->rchild);      //递归输出 R 
	}
}


int main()
{
	BSTree T;
	CreateTree(&T);
	printf("第一次遍历二叉排序树: ");
	InOrder(T);
	printf("\n执行删除操作遍历二叉排序树:");
	DeleteBST(&T,5);   //删除给定值为 5的结点 
	InOrder(T);
	return 0;
}

结果

在这里插入图片描述

分析

建立这样一棵二叉排序树
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值