数据结构--二叉搜索树的操作集

本文详细介绍了如何实现二叉搜索树(BST)的插入和删除操作,包括查找父节点、插入新节点以及删除节点的逻辑。删除操作通过右子树的最小节点或左子树的最大节点来替换被删除节点,确保了树的平衡。代码中包含了查找、插入、删除和查找最小/最大节点的函数实现。
摘要由CSDN通过智能技术生成

这是一个pta的题目,删除我没有用递归来写,写起来有些麻烦,但是总归是写出来了,查找函数我使用了嵌套,因为我还需要一个查找父节点的函数,所以直接封装了查找父节点的函数

需要提示的内容都在注释里了

/* 你的代码将被嵌在这里 */
//返回指定元素的父节点,返回空为根节点或者空树
Position FindPre(BinTree BST, ElementType X) {
	BinTree T = BST;
	BinTree pre = NULL;
	while (T != NULL) {
		//先判断是否相等
		if (X == T->Data)
			break;
		pre = T;
		if (X < T->Data) {
			T = T->Left;
			continue;
		}
		if (X > T->Data) {
			T = T->Right;
			continue;
		}
			
	}
	return pre;
}
//返回一个节点
BinTree getNode(ElementType X) {
	BinTree t = (struct TNode*)malloc(sizeof(struct TNode));
	t->Data = X;
	t->Left = NULL;
	t->Right = NULL;
	return t;
}
BinTree Insert(BinTree BST, ElementType X) {
	//空树的情况
	if (BST == NULL)
		return getNode(X);
	BinTree pre = FindPre(BST, X);// 返回要插入位置的父节点
	//如果为空,表示当前树只有一个节点(则父节点就为根)
	if (pre == NULL)
		pre = BST;
	//判断
	if (X < pre->Data&&pre->Left == NULL) {
		pre->Left = getNode(X);
	}
		
	if (X > pre->Data&&pre->Right == NULL) {
		pre->Right = getNode(X);
	}
	return BST;
}
//删除元素,使用右子树的最小节点替代原来节点的位置
BinTree Delete(BinTree BST, ElementType X) {
	//先查找到对应元素的节点
	BinTree del = Find(BST,X);//要删除的节点
	if (del == NULL) {
		//找不到或者空树的情况都是x不在树中,可以一起讨论
		printf("Not Found\n");
		return BST;
	}
	
	BinTree delR = del->Right;//要删除的节点的右孩子
	BinTree delL = del->Left;//要删除节点的左孩子
	int isBase = 0;//判断要删除的元素是否为根节点
	//判断是否为根节点
	if (del == BST)
		isBase = 1;
	//右孩子不为空
	if (delR != NULL ) {
		//非根节点,则先断开其父节点的连接
		BinTree father = FindPre(BST, X);
		if (!isBase) {
			if (X < father->Data)
				father->Left = NULL;
			else father->Right = NULL;
		}
		//找右子树的一个最小元素
		BinTree minNum = FindMin(delR);
		//如果最小元素为本身
		if (minNum == delR) {
			//要删除元素的父节点指向(如果非根节点)
			if (!isBase) {
				if (minNum->Data < father->Data)
					father->Left = minNum;
				else father->Right = minNum;
			}

			//最小节点指向要删除元素的左子树
			minNum->Left = delL;
			//释放资源
			free(del);
			//如果为根节点
			if (isBase)
				BST = minNum;
			//父节点连接替代节点
			else {
				if (minNum->Data < father->Data)
					father->Left = minNum;
				else
					father->Right = minNum;
			}
				
			return BST;
		}
		//最小元素为右孩子的最左元素
		else {
			//找到该最小元素的父节点,断开与最小元素的连接
			BinTree minPre = FindPre(delR,minNum->Data);
			minPre->Left = NULL;
			//将最左元素的右孩子给其父节点的左指针
			minPre->Left = minNum->Right;
			//指向左右孩子
			minNum->Left = delL;
			minNum->Right = delR;
			//如果为根节点
			if (isBase)
				BST = minNum;
			//非根节点,父节点连接
			else {
				if (minNum->Data < father->Data)
					father->Left = minNum;
				else
					father->Right = minNum;
			}
			//释放资源
			free(del);
			return BST;
		}
	
	}
	//右孩子为空且左孩子不为空(找左孩子的最大节点)
	else if (delR == NULL&&delL!=NULL) {
		//获取最大值
		BinTree maxNum = FindMax(delL);
		BinTree father = FindPre(BST, X);//返回要删除元素的父节点
		//断开非根节点的父节点的连接
		if (!isBase) {
			if (X < father->Data)
				father->Left = NULL;
			else father->Right = NULL;
		}
		//如果最大元素就是左孩子本身
		if (maxNum == delL) {
			//如果为根节点(此时不存在右子树)
			if (isBase) {
				//直接返回最大值节点
				free(del);
				return maxNum;
			}
			//非根节点
			else {
				if (maxNum->Data < father->Data)
					father->Left = maxNum;
				else father->Right = maxNum;
				free(del);
				return BST;
			}
		}
		//最大元素非左孩子本身(左孩子的最右节点)
		else {
			//找到最大元素的父节点并断开连接
			BinTree maxpre = FindPre(BST, maxNum->Data);
			
			maxpre->Right = NULL;
			//开始连接左右孩子
			maxNum->Left = delL;
			maxNum->Right = delR;
			if (isBase)
				BST = maxNum;
			else {
				//父节点连接
				if (maxNum->Data < father->Data)
					father->Left = maxNum;
				else father->Right = maxNum;
			}
			free(del);
			return BST;
		}
	}
	//左右孩子都为空
	else if (delR == NULL && delL == NULL) {
		//先判断要删除的元素是否为根节点
		if (del == BST) {
			//等于根节点,直接释放
			free(del);
			return NULL;
		}
		//不等于根节点
		else{
			//找到该元素的父节点,并置空
			BinTree p = FindPre(BST,X);
			if (X < p->Data) {
				p->Left = NULL;
			}
			else
			{
				p->Right = NULL;
			}
			//释放资源
			free(del);
			return BST;
			
		}
	}
	return BST;
}

//搜索指定元素,返回这个元素的节点地址
Position Find(BinTree BST, ElementType X) {
	BinTree T = FindPre(BST, X);
	//为空,则为空数或根节点,直接返回
	if (T == NULL) {
		return BST;
	}
	if (X < T->Data)
		return T->Left;
	else 
		return T->Right;
}
Position FindMin(BinTree BST) {
	if (BST == NULL)
		return NULL;
	//一直往左子树遍历
	while (BST->Left!=NULL){
		BST = BST->Left;
	}
	return BST;
}
Position FindMax(BinTree BST) {
	if (BST == NULL)
		return NULL;
	while (BST->Right!=NULL){
		BST = BST->Right;
	}
	return BST;
}

最后提交

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孔雀南飞梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值