删除二叉搜索树的节点(C语言)

删除二叉搜索树节点的三种情景:

情景1:删除的节点没有子树

如图,删除元素10,我们只需要将它的父节点9的右指针指向NULL,释放元素10的节点;

 代码:

if (root->left == NULL && root->right == NULL) //节点没有左节点和右节点
		{
			free(root); //释放内存
			root = NULL;
		}

情景2:删除的节点有一个子树(左右皆可)

如图,我们想删除节点10,但是节点10有一个右节点,那么我们可以将节点10的父节点指向节点10的右节点,再释放节点10的内存;

 代码:


		else if (root->left == NULL) //有右节点
		{
			struct Node* temp = root; 
			root = root->right; // 将 root 指针更新为指向当前节点的右子节点
			free(temp); //释放
		}
		else if (root->right == NULL) //有左节点
		{
			struct Node* temp = root;
			root = root->left;
			free(temp);
		}

情景3:删除的节点具有左节点和右节点

如图,我们想删除掉节点13,那么我们需要找到右子树最小值(左子树最大值)来替换掉删除节点的数据,然后将子树最值节点删除掉;

 代码:

struct Node* Min(struct Node* root)
{
if (root->left == NULL) //退出条件
{
	return root;
}
Min(root->left); //由于是二叉搜索树,所以左子树存放的是小值
}

if(root->left != NULL&&root->right != NULL)
{
	struct Node* temp = Min(root->right); //找出右子树最小值
	root->data = temp->data; //将删除值更新为右子树最小值
	root->right = delete(root->right, temp->data);//将最值节点删除
}

完整代码:

struct Node* Min(struct Node* root)
{
	if (root->left == NULL)
	{
		return root;
	}
	Min(root->left);

}
struct Node* delete(struct Node* root, int value) //value是删除节点数据
{
	if (root == NULL)
	{
		return root;
	}
	else if (root->data > value) //遍历左子树
	{
		root->left = delete(root->left, value);
	}
	else if (root->data < value) //遍历右子树
	{
		root->right = delete(root->right, value);
	}
	else //找到value对应节点
	{
		if (root->left == NULL && root->right == NULL) //节点没有左节点和右节点
		{
			free(root); //释放内存
			root = NULL;
		}
		else if (root->left == NULL) //有右节点
		{
			struct Node* temp = root; 
			root = root->right; // 将 root 指针更新为指向当前节点的右子节点
			free(temp); //释放
		}
		else if (root->right == NULL) //同理
		{
			struct Node* temp = root;
			root = root->left;
			free(temp);
		}
		else //同时有左节点和右节点
		{
			struct Node* temp = Min(root->right); //找出右子树最小值
			root->data = temp->data; //将删除值更新为右子树最小值
			root->right = delete(root->right, temp->data); //将右子树最小值的节点删除
		}
	}
	return root; //返回指针
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值