c++实现简单搜索二叉树<K,V>形

本文介绍了使用C++编写的模板类BSTreeNode和BSTree,详细阐述了如何构造节点、插入键值对、删除节点以及在搜索二叉树中查找特定键的操作。
摘要由CSDN通过智能技术生成

搜索二叉树

搜索二叉树本质:左节点比我小 右节点比我大
在这里插入图片描述

节点类

BSTreeNode:给自身节点封装一个类 用这个类来添加节点的操作
我们写的是一个key.value型的搜索二叉树

template<class K,class V>
struct BSTreeNode
{
	typedef BSTreeNode<K,V> Node;
	Node* _left;//左孩子
	Node* _right;//右孩子
	K _key;//建
	V _value;//值
};

BSTreeNode(节点类的构造)

BSTreeNode(const K& key, const V& value)
		: _left(nullptr)
		, _right(nullptr)
		, _key(key)
		, _value(value)
	{}

BSTree(功能实现类)

因为我们实现的是key,value型的所以模版是K,V
类中变量

template<class K,class V>
class BSTree
{
	typedef BSTreeNode<K,V> Node;
private:
	Node* _root;
};

Insert(插入)

首先:要判断是否为空树 如果是空树直接new一个新节点当根节点
还有就是建立一个cur让其等于根节点
用一个parent记录cur的父节点
用他们中的key值比较谁大谁小
小的往左走,大的往右走
走到合适位置,new一个新节点插入到树中

bool Insert(const K& key,const V& value)
{
	if (_root == nullptr)//树为空的情况
	{
		_root = new Node(key,value);
		return true;
	}
	Node* parent = nullptr;//因为cur是局部变量函数走完会销毁,所以增加一个指针 链接cur
	Node* cur = _root;
	while (cur)
	{
		if (cur->_key < key)
		{
			parent = cur;
			cur = cur->_right;
		}
		else if (cur->_key > key)
		{
			parent = cur;
			cur = cur->_left;
		}
		else
		{
			return false;
		}
	}
	cur = new Node(key,value);
	if (parent->_key < key)//大就链右边 小链左边
	{
		parent->_right = cur;
	}
	else
	{
		parent->_left = cur;
	}
	return true;
}

Erase(删除)

看代码中的注释

bool Erase(const K& key)
{
	Node* parent = nullptr;//记录父节点
	Node* cur = _root;//从根开始找
	while (cur)
	{
		//大了往右 小了往左
		if (cur->_key < key)
		{
			parent = cur;
			cur = cur->_right;
		}
		else if (cur->_key > key)
		{
			parent = cur;
			cur = cur->_left;
		}
		else//找到节点
		{
			if (cur->_left == nullptr)//左树为空
			{
				if (cur == _root)//头节点没有左子树
				{
					_root = cur->_right;
				}
				else//不为根节点
				{
					if (cur == parent->_right)//自身为父节点的右节点
					{
						//让自己的右节点成为父节点的右节点
						parent->_right = cur->_right;
					}
					else//左节点
					{
						//让我的右节点成为父节点的左节点
						parent->_left = cur->_right;
					}
				}
				delete cur;//删掉自己这个节点
				return true;
			}
			else if (cur->_right == nullptr)//右树为空
			{
				if (cur == _root)//头节点没有右子树
				{
					_root = cur->_left;
				}
				else
				{
					//让自己的左节点代替自己
					if (cur == parent->_right)
					{
						parent->_right = cur->_left;
					}
					else
					{
						parent->_left = cur->_left;
					}
				}
				delete cur;//删除节点
				return true;
			}
			else
			{
				//左右都不为空
				//找到右数中最小的代替自己
				Node* rightMin = cur->_right;
				//不能为空 如果为空的话 
				//要删的是头节点 会让空的_left指向他 会崩溃
				Node* father = cur;//定义这个为rightMin的父节点
				while (rightMin->_left)//找右树中的最小
				{
					father = rightMin;
					rightMin = rightMin->_left;
				}
				cur->_key = rightMin->_key;//交换值
				//如果 相等 那么才让他的父节点左指向他自身节点的右
				if (rightMin == father->_left)
				{
					father->_left = rightMin->_right;
				}
				else//不想等就是说明的头节点 那么就要让头节点的右指向他的右
				{
					father->_right = rightMin->_right;
				}
				delete rightMin;
				return true;
			}
		}
	}
	return false;
}

Find(查找这个节点)

大了往右 小了往左 找到返回节点 没找到返回空

Node* Find(const K& key)
{
	Node* cur = _root;
	while (cur)
	{
		
		if (cur->_key < key)
		{
			cur = cur->_right;
		}
		else if (cur->_key > key)
		{
			cur = cur->_left;
		}
		else
		{
			return cur;
		}
	}
	return nullptr;
}
  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

dabai__a

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

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

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

打赏作者

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

抵扣说明:

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

余额充值