二叉查找树的删除操作

对于二叉树的删除操作来说,存在三种情况
**1.**当删除节点为叶节点的时候,此时将节点置为空
**2.**当删除节点为根节点且该根节点只有一个子树的时候,此时需要替换掉删除元素,最后再进行释放
**3.**当删除节点为根节点且根节点存在两个子树的时候,此时我们可以选择替换左子树的最大元素,或者右子树的最小元素

C代码如下

Tree de_tree(Item data, Tree t)			//二叉树元素的删除
{
	Tree parent;						//根节点
	Tree curTree;						//现在的节点
	Tree fTree = t;						//找到的节点位置

	while (fTree)
	{
		if (data == fTree->element)				//找到元素则退出
			break;
		else if (data < fTree->element)			//如果元素小于当前元素 则向左查找
		{
			parent = fTree;
			fTree = fTree->lchild;
		}
		else
		{										//否则向右查找
			parent = fTree;
			fTree = fTree->rchild;
		}
	}
	if (!fTree)									//如果没有找到要删除的元素的话 直接返回t
		return t;

	///删除的第一种情况 当找到的元素为叶节点的时候
	if (!fTree->lchild && !fTree->rchild)
	{
		if (fTree == t)						//表示该树只有一个根节点
		{
			t = NULL;						//将根节点置为NULL
			free(fTree);
		}
		else if (fTree == parent->lchild)	//该叶节点为左子树
		{
			parent->lchild = NULL;			//左子树置为NULL
			free(fTree);
		}
		else
		{									//该叶节点为左子树
			parent->rchild = NULL;			//右子树置为NULL
			free(fTree);
		}
		return t;
	}
	///删除的第二种情况 左子树或右子树为空
	else if (!fTree->lchild || !fTree->rchild)
	{
		if (fTree == parent->lchild)			//如果当前要删除的节点是父节点的左子树的时候
		{
			if (fTree->lchild)					//删除的节点只有一个左子树
				parent->lchild = fTree->lchild;	//那么跳过要删除的节点并替换为下个左子树
			else								//删除的节点只有一个右子树
				parent->lchild = fTree->rchild;	//替换为下个右子树
		}
		else
		{										//如果当前要删除的节点是父节点的右子树的时候
			if (fTree->lchild)					//只有一个左子树
				parent->rchild = fTree->lchild;
			else								//只有一个右子树
				parent->rchild = fTree->rchild;
		}
		free(fTree);
		return t;
	}

	///删除的第三种情况 也就是当左子树和右子树都不为空的情况下进行删除
	///此时可以选择将删除元素替换为左子树的最大值和右子树的最小值
	else
	{
		parent = fTree;
		curTree = fTree->lchild;			//此处我们选择左子树的最大值

		while (curTree->rchild)				//找到最右下角的位置,也就是左子树中的最大值
		{
			parent = curTree;				//每次向下寻找
			curTree = curTree->rchild;
		}

		fTree->element = curTree->element;			//交换最大值
		if (parent == fTree)						//表示左子树的最大值为要删除元素的左子树
			parent->lchild = curTree->lchild;		//跳过该元素
		else
			parent->rchild = curTree->lchild;		//因为已经交换了最大值,那么我们就需要跳过该节点

		free(curTree);
		return t;
	}

}

代码已经很详细的解释了如何进行操作的,祝大家学习顺利!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

David_TD

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

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

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

打赏作者

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

抵扣说明:

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

余额充值