搜索二叉树的应用

搜索二叉树的应用分为:

      key模型:找key

      key和value模型:通过key找到value的值

key的模型就是搜索二叉树。

而key和value模型就是通过值找值,举个栗子:当过安检时是不是刷身份证,那是如何得知乘客是否购买了票呢?

就是通过key和value模型,通过身份的ID寻找到购票的信息

只需要增加模板参数

并对余下个别功能进行修改如find,如insert

中英文互译

完整代码:

template<class k,class v>
struct BSTreenode
{
	BSTreenode<k,v>* left;
	BSTreenode<k,v>* right;
	k _key;
	v _value;

	BSTreenode(k key,v value)
		:left(nullptr)
		, right(nullptr)
		, _key(key)
		,_value(value)
	{

	}
};
template<class k,class v>
class BSTree
{
	typedef BSTreenode<k,v> node;//重写结点名字,方便
public:
	bool erase(const k& key)
	{
		//先去找
		//双指针法
		node* cur = _root;
		node* parent = nullptr;
		while (cur)
		{
			if (cur->_key > key)
			{
				parent = cur;
				cur = cur->left;
			}
			else if (cur->_key < key)
			{
				parent = cur;
				cur = cur->right;
			}
			else
			{
				//找到了,分情况讨论
				//只有一种的情况下:待删结点的子结点为右边
				//如果cur两边都没有结点符合
				if (cur->left == nullptr)
				{
					//确定parent的左连接到cur还是右连接到cur
					if (parent->left == cur)
					{
						parent->left = cur->right;
					}
					else
					{
						parent->right = cur->right;
					}
					delete cur;
					return true;
				}//待删结点的子结点为左边
				else if (cur->right == nullptr)
				{
					//确定parent的左连接到cur还是右连接到cur
					if (parent->left == cur)
					{
						parent->left = cur->left;
					}
					else
					{
						parent->right = cur->left;
					}
					delete cur;
					return true;
				}
				else
				{

					//只剩下两个结点的情况
					node* rightsmall = cur->right;
					node* rightsmallparent = cur;
					while (rightsmall->left)//一直往左走就找到右子树的最小的
					{//当这个条件结束rightsmall的左边已经没有值了所以就是最小的
						rightsmallparent = rightsmall;
						rightsmall = rightsmall->left;
					}
					cur->_key = rightsmall->_key;//赋值
					//替代完成
					//删除替代的原位置
					if (rightsmall->left == nullptr)
					{
						if (rightsmallparent->left == rightsmall)
						{
							rightsmallparent->left = rightsmall->right;
						}
						else
						{
							rightsmallparent->right = rightsmall->right;

						}
						//因为rightsmall一直往左走
						 //所以是rightsmallparent的左孩子
					}
					else
					{
						if (rightsmallparent->left == rightsmall)
						{
							rightsmallparent->left = rightsmall->left;
						}
						else
						{
							rightsmallparent->right = rightsmall->left;
						}

					}
					delete rightsmall;
					return true;
				}
				return false;
			}
		}
	}

	bool insert(k key,v value)
	{
		//两种情况;
		//树里没有数据和有数据俩种
		if (_root == nullptr)
		{
			_root = new node(key,value);//开辟一个node对象然后调用初始化构造
			return true;
		}
		else
		{
			//有数据,要找到正确位置
			node* parent = nullptr;
			node* cur = _root;
			while (cur)
			{
				if (cur->_key > key)//证明待插入元素应该往左边
				{
					parent = cur;//cur是探测作用,parent是保存上一个指针地址
					cur = cur->left;

				}
				else if (cur->_key < key)//证明待插入元素应该往右边
				{
					parent = cur;
					cur = cur->right;
				}
			}
			//当cur为nullptr就要找到待插入位置。
			//但是,还要确定插在parent的左还是右
			if (parent->_key > key)
			{
				parent->left = new node(key,value);
			}
			else
			{
				parent->right = new node(key,value);
			}
		}
	}
	void _InOrder(node* root)
	{
		if (root == nullptr)
		{
			return;
		}
		_InOrder(root->left);
		cout << root->_key << " "<<root->_value<<endl;
		_InOrder(root->right);
	}
	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}
	node* Find(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;

	}
private:
	node* _root = nullptr;//定义头指针
};
int main()
{
	BSTree<string, string> _b;
	_b.insert("sort", "排序");
	_b.insert("tree", "树");
	_b.insert("stack", "栈");
	_b.insert("list", "链表");
	_b.insert("queue", "队列");

	string s;
	while (cin >> s)
	{
		BSTreenode<string, string>* ret = _b.Find(s);
		if (ret)
		{
			cout << ret->_value << endl;
		}
		else
		{
			cout << "查无此词" << endl;
		}

	}
}

统计数据

统计水果

统计水果完整代码(同用于上面的搜索二叉树的原理)

int main()
{
	//统计数据
	string strArr[] = { "西瓜","樱桃", "西瓜", "香蕉", "西瓜", "苹果", "西瓜","车厘子" };
	BSTree<string, int> countTree;
	for (auto a : strArr)
	{
		BSTreenode<string, int>* ret = countTree.Find(a);
		if (ret == nullptr)
		{
			countTree.insert(a, 1);
		}
		else
		{
			ret->_value += 1;
		}

	}
	countTree.InOrder();
}

注意:为什么使用搜索二叉树因为搜索”效率高“

如果插入的数据是有序的或着接近有序的?那搜索树的效率就没办法保证了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值