二叉搜索树-利用循环删除二叉搜索树算法

本文详细介绍了如何使用循环查找方法来实现二叉搜索树中节点的删除操作。具体包括寻找目标节点、父节点以及找到最大或最小值的节点。删除操作根据节点的左右子节点情况分为四种情况,并提供了相应的处理策略,确保了树的平衡和正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

感谢:爱你是长久之计~博主提供思想(私下,技术交流)

利用循环删除二叉搜索树算法-算法流程图

在这里插入图片描述

利用循环删除二叉搜索树算法-算法实现


//通过循环查找节点
Tree::Tree_Node* Loop_FindTreeNode(Tree::Tree_Node*& root, const Tree::Tree_value &value) {

	auto  currentNode = root;
	while (currentNode&& currentNode->value != value){
		if ((currentNode->value> value)){
			currentNode = currentNode->LeftChild;
		}		
		else {
			currentNode = currentNode->RightChild;
		}

	}

	return currentNode;

}

Tree::Tree_Node* Loop_FindTreeParentNode(Tree::Tree_Node*& node, const Tree::Tree_value& value) {

	Tree::Tree_Node* Parent = nullptr;
	auto  currentNode = node;
	while (currentNode && currentNode->value != value) {
		Parent = currentNode;
		if ((currentNode->value > value )) {
			currentNode = currentNode->LeftChild;
		}
		else {
			currentNode = currentNode->RightChild;
		}

	}
	//如果currentNode != nullptr 返回Parent 父亲节点 否则返回 nullptr
	return currentNode != nullptr ? Parent : nullptr;

}

int *Loop_FindTreeMaxOrMinValue(Tree::Tree_Node*& node) {

	int* MaxOrMinValue = nullptr;
	auto  currentNode = node;
	if (currentNode){


		if (currentNode->LeftChild) {

			currentNode = currentNode->LeftChild;

			while (currentNode->RightChild) {

				currentNode = currentNode->RightChild;

			}

			MaxOrMinValue = &currentNode->value;

		}
		else if (currentNode->RightChild){

			currentNode = currentNode->RightChild;

			while (currentNode->LeftChild) {

				currentNode = currentNode->LeftChild;

			}

			MaxOrMinValue = &currentNode->value;

		}
	}
	//如果MaxOrMinValue != nullptr 返回MaxOrMinValue  否则返回 nullptr
	return MaxOrMinValue != nullptr ? MaxOrMinValue : nullptr;

}


 inline bool Is_TreeNodeSame( Tree::Tree_Node*& treeNodeOnce,  Tree::Tree_Node*& treeNodeTwo) {
	return (treeNodeOnce == treeNodeTwo);
}

 void  unlinkTreeNodeLeftChild(Tree::Tree_Node*& TargetNode, Tree::Tree_Node* SourceNode = nullptr) {
	

	 TargetNode ? TargetNode->LeftChild = SourceNode : TargetNode;
 }
 void  unlinkTreeNodeRightChild(Tree::Tree_Node*& TargetNode, Tree::Tree_Node* SourceNode = nullptr) {

	 TargetNode ? TargetNode->RightChild = SourceNode : TargetNode;
 }

 void Destroy_treeNode(Tree::Tree_Node*& TreeNode, nullptr_t where=nullptr) {
	 delete TreeNode;
	 TreeNode = where;
 }


//循环方式删除二叉搜索树结点
 bool Loop_DeleteTreeNode(Tree::Tree_Node*& root, const Tree::Tree_value& value) {

	 bool ret = false;


	 //当前 节点
	 Tree::Tree_Node* currentNode = Loop_FindTreeNode(root, value);
	 //当前结点父节点
	 Tree::Tree_Node* currentParentNode = Loop_FindTreeParentNode(root, value);

	 ret = currentNode;
	 if (ret) {
		 //当前节点的左子节点有节点 并且 当前节点的右子节点有节点 的情况
		 if (!currentNode->LeftChild && !currentNode->RightChild) {

			 //当前节点不是根节点
			 if (!Is_TreeNodeSame(currentNode, root)) {
				 //当前父节点不为空
				 if (currentParentNode) {
					 //当前父节点的左子节点 == 当前节点
					 if (Is_TreeNodeSame(currentParentNode->LeftChild, currentNode)) {
						 //调用断开树的节点的左子节点
						 unlinkTreeNodeLeftChild(currentParentNode);
					 }
					 //当前父节点的右子节点 == 当前节点
					 else {
						 //调用断开树的节点的右子节点
						 unlinkTreeNodeRightChild(currentParentNode);
					 }
				 }
			 }
			 else {
				 //销毁树的节点
				 Destroy_treeNode(currentNode);
				 root = currentNode;
			 }
			
			 //销毁树的节点
			 Destroy_treeNode(currentNode);
		 }//当前节点的左子节点没有节点 并且 当前节点的右子节点没有节点 的情况	
		 else if (currentNode->LeftChild && !currentNode->RightChild) {
			 if (!Is_TreeNodeSame(currentNode, root)) {
				 //当前父节点不为空
				 if (currentParentNode) {
					 //当前父节点的左子节点 == 当前节点
					 if (Is_TreeNodeSame(currentParentNode->LeftChild, currentNode)) {
						 //调用断开树的节点的左子节点
						 unlinkTreeNodeLeftChild(currentParentNode, currentNode->LeftChild);
					 }
					 else {
						 //调用断开树的节点的右子节点
						 unlinkTreeNodeRightChild(currentParentNode, currentNode->LeftChild);
					 }
				 }
						
			 }
			 else {
				 //根节点向左子节点 方向走
				 root = root->LeftChild;
			 }

			 //销毁树的节点
			 Destroy_treeNode(currentNode);
		 }
		 //当前节点的左子节点没有节点 并且 当前节点的右子节点有节点 的情况
		 else if (!currentNode->LeftChild && currentNode->RightChild) {
			 if (!Is_TreeNodeSame(currentNode, root)) {

				 if (currentParentNode) {

					 //当前父节点的右子节点 == 当前节点
					 if (Is_TreeNodeSame(currentParentNode->LeftChild, currentNode)) {
						 //调用断开树的节点的左子节点
						 unlinkTreeNodeLeftChild(currentParentNode, currentNode->RightChild);
					 }
					 else {
						 //调用断开树的节点的右子节点
						 unlinkTreeNodeRightChild(currentParentNode, currentNode->RightChild);
					 }	
				 }				
			 }
			 else {
				 //根节点向右子节点 方向走
				 root = root->RightChild;
			 }
			 //销毁树的节点
			 Destroy_treeNode(currentNode);
		 }
		 //当前节点的左子节点有节点 并且 当前节点的右子节点有节点 的情况
		 else {
			 //自动获取最大或者最小值
			const int* MaxOrMinValue = Loop_FindTreeMaxOrMinValue(currentNode);

			 ret = MaxOrMinValue;
			 if (ret) {

				 //缓存需要待删除结点
				 auto CacheNode = Loop_FindTreeNode(root, *MaxOrMinValue);
				 //缓存需要删除的父节点
				 auto CacheNodeParent = Loop_FindTreeParentNode(root, *MaxOrMinValue);
				 ret = CacheNodeParent;
				 if (ret){
					 //当前结点的数据改为最大或者最小值
					 currentNode->value = *MaxOrMinValue;
					 
					 //缓存需要待删除父节点的左子节点==CacheNode
					 if (CacheNodeParent->LeftChild == CacheNode) {
						 
						 //缓存节点的左子节点有节点 并且 缓存节点的右子节点没有节点 的情况
						 if (CacheNode->RightChild && !CacheNode->LeftChild) {
							 //调用断开树的节点的左子节点 
							 unlinkTreeNodeLeftChild(CacheNodeParent, CacheNode->RightChild);
						 }
						 else {
							 //调用断开树的节点的左子节点
							 unlinkTreeNodeLeftChild(CacheNodeParent);
						 }
					 } //缓存待删除结点
					 else  if (CacheNodeParent->RightChild == CacheNode) {
						 //缓存待删除结点的左子节点有节点 并且 缓存待删除结点的右子节点没有节点 的情况
						 if (CacheNode->LeftChild && !CacheNode->RightChild) {
							 unlinkTreeNodeRightChild(CacheNodeParent, CacheNode->LeftChild);
						 }
						 else {
							 //调用断开树的节点的右子节点
							 unlinkTreeNodeRightChild(CacheNodeParent);
						 }
					 }

					 Destroy_treeNode(CacheNode);
				 }
			 }
		 }
	 }

	 return ret;
 }


 void TreeErase(Tree& tree, const Tree::Tree_value& value) {

	 Loop_DeleteTreeNode(tree.Root, value);
	 tree.size -= 1;

 }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小森程序员

若能帮助到你,小费自愿付费

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

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

打赏作者

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

抵扣说明:

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

余额充值