二叉搜索树

1、概念

就是普通树的一种,然后具有其特殊的性质。

其左子树的所有值都小于根节点的值。

其右子树的所有值都大于根节点的值。

左右树都是二叉搜索树。

我们在这里直接利用一个数组进行创建一个搜索二叉树。

(7-2-4-6-3-1-5)  以8为根节点进行创建。

 

比根节点小的,就放在左边,比根节点大的,就放在右边,各位可以按照这个图了解一下。

2、增删查改的实现

我们首先要对树进行前期的准备,看代码。

	template<class T>
	struct BSTreeNode
	{
		typedef BSTreeNode<T> Node;//定义节点的属性

		Node* _left;
		Node* _right;
		T _key;

		BSTreeNode(const T& key)//节点初始化
			:_left(nullptr)
			, _right(nullptr)
			, _key(key)
		{}
	};

 

2.1、查找

这里的查找其实和二叉树差不多,但是这里实现应该是更简单一些,空就返回,小于查找值就去right,大于查找值就去left。但在这里我们用更简单的递归实现。


  bool _FindR(Node* root, const T& key)//找到就返回true,没有就返回false
{//利用递归实现
			if (root == nullptr)
				return false;

			if (root->_key < key)
			{
				return _FindR(root->_right, key);
			}
			else if (root->_key > key)
			{
				return _FindR(root->_left, key);
			}
			else
			{
				return true;
			}
}

2.2、增加—插入 

 这里其实也很好理解,就是找到通过递归找到正确位置后插入,然后将true返回给最初的函数。

bool _InsertR(Node*& root, const T& key)
		{
			if (root == nullptr)//找到正确位置后,直接将节点插入
			{
				root = new Node(key);
				return true;
			}

			if (root->_key < key)
			{
				return _InsertR(root->_right, key);
			}
			else if (root->_key > key)
			{
				return _InsertR(root->_left, key);
			}
			else
			{
				return false;
			}
		}

2.3、删除

这里的删除就很有讲究了, 详细解析在代码的注释里。

bool _EraseR(Node*& root, const T& key)
		{
			if (root == nullptr)
				return false;

			if (root->_key < key)
			{
				return _EraseR(root->_right, key);
			}
			else if (root->_key > key)
			{
				return _EraseR(root->_left, key);
			}
			else
			{
				Node* del = root;//此时找到我们要删除的节点
				if (root->_right == nullptr)//右边为空,那就把左边直接覆盖到此节点
				{
					root = root->_left;
				}
				else if (root->_left == nullptr)//反之,直接用右边的覆盖
				{
					root = root->_right;
				}
				else//左右节点都有孩子,特殊处理
				{
					Node* rightMin = root->_right;//我们这里利用右节点最小值(这里也可用左节点最大值,效果相同)来替代这个被删除的节点
//因为这两个值一定是大于被删除节点的左节点,小于右节点
					while (rightMin->_left)//找最左边的值
					{
						rightMin = rightMin->_left;
					}

					swap(root->_key, rightMin->_key);//直接交换

					return _EraseR(root->_right, key);//将交换后的值删除,也就是结尾的那个值
				}

				delete del;
				return true;
			}
		}

2.4、改 

这里的改就没有什么大的意义了,其实就复用一个查找的函数,然后直接替换那个被查找的数就可以了。 


  bool _replaceR(Node* root, const T& key,int x)//找到就返回true,没有就返回false
{//利用递归实现
			if (root == nullptr)
				return false;//修改失败,也就是没找到

			if (root->_key < key)
			{
				return _FindR(root->_right, key);
			}
			else if (root->_key > key)
			{
				return _FindR(root->_left, key);
			}
			else
			{
                root->_key=x;
				return true;//修改成功
			}
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值