数据结构-二叉树-二叉搜索树

一、概念

二叉搜索树又称二叉排序树,它或者是一棵空树,或者具有以下性质的二叉树:

若它的左子树不为空,则左树上所有节点的值都小于根节点的值。

若它的右子树不为空,则右子树上所有节点的值都大于根节点的值。

它的左右子树也分别为二叉搜索树。最多找O(N)。

二、查找、插入、删除

插入

cpp 复制代码
bool Insert(K& k)
{
	
	if (_root == nullptr)
	{
		_root = new BSNode(k);
		return true;
	}
	BSNode* cur = _root;
	BSNode* parent = nullptr;
	while (cur)
	{
		if (cur->_k < k)
		{
			parent = cur;
			cur = cur->_right;
		}
		else if (cur->_k > k)
		{
			parent = cur;
			cur = cur->_left;
		}
	}
	if (parent->_k < k)
	{
		parent->_right = new BSNode(k);
	}
	else if (parent->_k > k)
	{
		parent->_left = new BSNode(k);
	}
	else
	{
		return false;
	}
	return true;
}

查找

cpp 复制代码
bool Find(K k)
{
	BSNode* cur = _root;
	while (cur)
	{
		if (cur->_k < k)
		{
			cur = cur->_right;
		}
		else if (cur->_k > k)
		{
			cur = cur->_left;
		}
		else
		{
			return true;
		}
	}
	return false;
}

删除

依次删除7、14、3、8。7和14属于直接删除的场景

3、8属于需要替换法进行删除的场景。

1、没有孩子

2、一个孩字

3、两个孩子,需要进行替换,也就是替换法,用左子树的最大节点或者右子树的最小节点。

最大节点为最右节点,最小节点就是最左节点 ,还需要处理要删除的节点为根节点,它没有左子树或者没有右子树的情况。

还有一种情况就是leftmax就是root的左子树的根,此时parent为nullptr所以我们需要让parent = cur

cpp 复制代码
void Erase(K& k)
{
	BSNode* cur = _root;
	BSNode* parent = nullptr;
	while (cur)
	{
		if (cur->_k < k)
		{
			parent = cur;
			cur = cur->_right;
		}
		else if (cur->_k > k)
		{
			parent = cur;
			cur = cur->_left;
		}
		else
		{
			//开始托孤
			//要删除的节点,左孩子为空
			if (cur->_left == nullptr)
			{
				//需要判断删除节点就是根节点的情况
				if (cur == _root)
				{
					_root = cur->_right;
				}
				else
				{
					if (parent->_right == cur)
					{
						parent->_right = cur->_right;
					}
					else
					{
						parent->_left = cur->_right;
					}
				}
				
			}
			else if (cur->_right == nullptr)
			{
				if (cur == _root)
				{
					_root = cur->_left;
				}
				else
				{
					if (parent->_right == cur)
					{
						parent->_right = cur->_left;
					}
					else 
					{
						parent->_left = cur->_left;
					}
				}
			}
			else //两个孩子的情况,就需要替代法来删除
			{
				//找到左子树中最大的节点
				BSNode* leftMax = cur->_left;
				//注意为什么这里等于cur;
				BSNode* parent = cur;  
				while (leftMax->_right)
				{
					parent = leftMax;
					leftMax = leftMax->_right;
				}
				//找到以后把删除节点和leftmax节点的值做交换
				std::swap(cur->_k, leftMax->_k);

				//我们该把父亲的那个孩子和cur节点的孩子连接起来呢需要判断
				if (parent->_left == leftMax)
				{
					parent->_left = leftMax->_left;
				}
				else
				{
					parent->_right = leftMax->_left;
				}

				cur = leftMax;
			}

			delete cur;
			cur = nullptr;
		}
	}
}

有序数组:二分查找,问题:插入删除效率不行

二叉搜索树:插入删除效率还行。

如果退化成下面的情况,插入删除的效率就变成了O(N),所以我们引出了AVL树红黑树B树系列。

接下来我们看一下递归版本的删除,插入和发现

cpp 复制代码
bool _EraseR(BSNode*& root, const K& k)
{
	
	if (root == nullptr)
	{
		return false;
	}
	if (root->_k < k)
	{
		_EraseR(root->_right, k);
	}
	else if (root->_k > k)
	{
		_EraseR(root->_left, k);
	}
	else
	{
		BSNode* del = root;
		if (root->_left == nullptr)
		{
			root = root->_right;
		}
		else if (root->_right == nullptr)
		{
			root = root->_left;
		}
		else
		{
			BSNode* leftMax = root->_left;
			while (leftMax->_right)
			{
				leftMax = leftMax->_right;
			}
			std::swap(leftMax->_k, root->_k);

			return _EraseR(root->_left, k);
		}
		delete del;
		del = nullptr;
		return true;
	}
}
bool _InsertR(BSNode*& root,const K& k)
{
	if (root == nullptr)
	{
		root = new BSNode(k);
		return true;
	}
	if (root->_k < k)
	{
		_InsertR(root->_right, k);
	}
	else if (root->_k > k)
	{
		_InsertR(root->_left, k);
	}
	else
	{
		return false;
	}
}
bool _FindR(BSNode* root, const K& k)
{
	if (root == nullptr)
		return false;
	BSNode* cur = root;
	if (cur->_k < k)
	{
		_FindR(root->_right, k);
	}
	else if (cur->_k > k)
	{
		_FindR(root->_left, k);
	}
	else
	{
		return true;
	}
}
相关推荐
阿Y加油吧21 分钟前
栈的经典应用:字符串解码 & 每日温度 深度解析
数据结构·python·算法
千谦阙听39 分钟前
数据结构最终章:万字详解排序算法!(内部排序)
c语言·数据结构·学习·算法·排序算法
断眉的派大星1 小时前
数据结构——指针
数据结构·算法
Magic-Yuan1 小时前
规范数据结构化处理难点分析
数据结构·人工智能
网安INF1 小时前
数据结构第四章复习:串
数据结构
动恰客流管家1 小时前
动恰3DV3丨展会客流统计解决方案:3D视觉技术赋能会展行业智慧化运营升级
大数据·数据结构·人工智能
沐苏瑶1 小时前
Java据结构深度解析:AVL 树与红黑树
数据结构·算法
2401_892070982 小时前
八大排序算法
数据结构·c++·排序算法
会编程的土豆2 小时前
【数据结构与算法】哈希表
数据结构·散列表
无敌昊哥战神2 小时前
【算法与数据结构】深入浅出回溯算法:理论基础与核心模板(C/C++与Python三语解析)
c语言·数据结构·c++·笔记·python·算法