STL——二叉搜索树

server/2025/1/11 8:53:43/

目录

二叉搜索树的概念

 ⼆叉搜索树的性能分析

 ⼆叉搜索树的插⼊

⼆叉搜索树的查找

⼆叉搜索树的删除

 中序遍历结果为升序序列


二叉搜索树的概念

⼆叉搜索树⼜称⼆叉排序树,它或者是⼀棵空树,或者是具有以下性质的⼆叉树
若它的左⼦树不为空,则左⼦树上所有结点的值都⼩于等于根结点的值
若它的右⼦树不为空,则右⼦树上所有结点的值都⼤于等于根结点的值
它的左右⼦树也分别为⼆叉搜索树
⼆叉搜索树中可以⽀持插⼊相等的值,也可以不⽀持插⼊相等的值,具体看使⽤场景定义,后续我 们学习map/set/multimap/multiset系列容器底层就是⼆叉搜索树,其中map/set不⽀持插⼊相等 值,multimap/multiset⽀持插⼊相等值

 ⼆叉搜索树的性能分析

最优情况下,⼆叉搜索树为完全⼆叉树(或者接近完全⼆叉树),其⾼度为: log 2 N
最差情况下,⼆叉搜索树退化为单⽀树(或者类似单⽀),其⾼度为: N
所以综合⽽⾔⼆叉搜索树增删查改时间复杂度为: O ( N )
中序遍历二叉搜索树得到一个升序序列
⼆分查找也可以实现 O (log 2 N ) 级别的查找效率,但是⼆分查找有两⼤缺陷:
1. 需要存储在⽀持下标随机访问的结构中,并且有序。 (有序数组
2. 插⼊和删除数据效率很低,因为存储在下标随机访问的结构中,插⼊和删除数据⼀般需要挪动数 据。

 ⼆叉搜索树的插⼊

1. 树为空,则直接新增结点,赋值给root指针
2. 树不空,按⼆叉搜索树性质,插⼊值⽐当前结点⼤往右⾛,插⼊值⽐当前结点⼩往左⾛,找到空位 置,插⼊新结点。
3. 如果⽀持插⼊相等的值,插⼊值跟当前结点相等的值可以往右⾛,也可以往左⾛,找到空位置,插 ⼊新结点。(要注意的是要保持逻辑⼀致性,插⼊相等的值不要⼀会往右⾛,⼀会往左⾛)
	bool Insert(const K& key){if (_root == nullptr){_root = new Node(key);		// 1、若根为空,则就插入在此处return true;}Node* parent = nullptr;	// 使用parent保存父节点,用于后续链接Node* cur = _root;while (cur){if (cur->_key < key)		// 2、不断递归寻找合适插入位置要满足左小右大的特点{parent = cur;cur = cur->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else{cout << "所要插入的值已经存在" << endl;return false;}}cur = new Node(key);if (parent->_key > key)			// 3、找到之后使用parent和cur进行新建结点的接入parent->_left = cur;elseparent->_right = cur;return true;}

⼆叉搜索树的查找

如果⽀持插⼊相等的值,意味着有多个x存在,⼀般要求查找中序的第⼀个x,如下图,查找3,要

找到1的右孩⼦的那个3返回。
    bool Find(const K& key){Node* cur = _root;while (cur){if (cur->_key == key)return true;else if (cur->_key > key)cur = cur->_left;elsecur = cur->_right;}return false;}

⼆叉搜索树的删除

父要接管删除节点的剩余结点

若cur的左为空,那么父节点要处理cur的右子树

若cur的右为空,那么父节点要处理cur的左子树

若cur的左右均不为空,那么就找cur右子树的最左结点进行接管,最后处理最左节点的右子树

三种情况,最终处理时又都有俩种 孩子在左、在右的情况。

	bool Erase(const K& key){Node* parent = nullptr;Node* cur = _root;while (cur)	// 遍历搜索树,寻找需要删除的结点位置{if (cur->_key > key){parent = cur;cur = cur->_left;}else if (cur->_key < key){parent = cur;cur = cur->_right;}else{// 此时找到了需要删除的结点位置,进行删除操作// 我的左为空,父亲处理我的右if (cur->_left == nullptr){if (cur == _root) // 左为空,并且cur为根_root = cur->_right;if (cur == parent->_right)parent->_right = cur->_right;else if (cur == parent->_left)parent->_left = cur->_right;delete cur;}// 我的右为空,父亲处理我的左else if (cur->_right == nullptr){if (cur == _root)// 右为空,并且cur为根_root = cur->_left;if (cur == parent->_right)parent->_right = cur->_left;elseparent->_left = cur->_left;delete cur;}else{// 左右均不为空,需要找右子树的最左(最小)结点来接管我的位置Node* minRightNode = cur->_right; //通过minRightNode 和 minRightParentNode* minRightParent = cur;	      //找右子树最左节点while (minRightNode->_left)  {minRightParent = minRightNode;minRightNode = minRightNode->_left; // 一直向最左移动,注意保存父节点位置}cur->_key = minRightNode->_key;			// 将结点的_key值进行替换即可if (minRightParent->_right != minRightNode)		// 处理minRightNode结点,只有俩种情况,一种minRightNode是minRightParent的左孩子、另一种是右孩子minRightParent->_left = minRightNode->_right;	// 如果minRightNode是左孩子,那么minRightParent要接管它的右子树elseminRightParent->_right = minRightNode->_right;	// 如果minRightNode是右孩子,那么minRightParent要接管它的左子树delete minRightNode;}return true;}}return false;}

 中序遍历结果为升序序列

 最开始没有写 InOrder() 函数,在main中进行调用时发生了 t.InOrder(??) 无法给左式括号内传参的问题,所以又加入了一个InOrder 和 _InOrder()俩个递归函数嵌套的形式。

template<class K>
class BSTree
{typedef BSTNode<K> Node;
public:	void InOrder(){_InOrder(_root);  cout << endl;}
private:void _InOrder(Node* root){if (root == nullptr)return;_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}Node* _root = nullptr;
};

 


http://www.ppmy.cn/server/157416.html

相关文章

云原生周刊:K8s 生态系统的五大趋势预测

开源项目推荐 Burrito Burrito 是一款 TACoS&#xff08;Terraform Automation and Collaboration Software&#xff09;Kubernetes Operator&#xff0c;旨在提供类似 Argo CD 的体验&#xff0c;用于管理和自动化 Terraform 工作流。通过 Burrito&#xff0c;用户可以在 Ku…

C#Halcon找线封装

利用CreateMetrologyModel封装找线工具时&#xff0c;在后期实际应用调试时容易把检测极性搞混乱&#xff0c;造成检测偏差&#xff0c;基于此&#xff0c;此Demo增加画线后检测极性的指引&#xff0c;首先看一下效果 加载测试图片 画线 确定后指引效果 找线效果 修改显示 UI代…

详细分析 创建并上传到 GitHub 仓库

目录 前言1. 从零创建并上传代码到 GitHub2. 将现有的本地仓库推送到 GitHub 前言 &#x1f91f; 找工作&#xff0c;来万码优才&#xff1a;&#x1f449; #小程序://万码优才/r6rqmzDaXpYkJZF 创建仓库的时候&#xff0c;平台已经有所提供流程&#xff01; 1. 从零创建并上传…

机器学习之基本概念 - 数据集、训练集、特征向量、独立同分布的

机器学习是对能通过经验自动改进的计算机算法的研究. ——汤姆米切尔(Tom Mitchell)[Mitchell, 1997] 思考一个问题&#xff1a; 如何让计算机能自动识别手写的数字&#xff1f; ————------------------———————分割线—————————————————-------…

部署HugeGraph

部署HugeGraph 这里以hugegraph1.2.0为例子&#xff0c;演示一下如何安装部署hugegraph 一、下载并安装JDK11 下载JDK11 https://www.oracle.com/java/technologies/downloads/#java11 使用scp命令将安装包上传到服务器 scp /path/to/local/file usernameserver_ip:/path/…

ue5 GAS 从零开始00

技能属性GAS 技能 属性 创建一个项目c 插件搜索 gameplay 保证这里勾选上 把这三个弄上去 “GameplayAbilities”,“GameplayTags”,“GameplayTasks” 这样就加载了三个模块 一定要先关ue 先关掉ue 生成 如果没编过&#xff0c;你就检查模块名字是不是没写对 一定要…

网络安全:守护数字世界的防线

在信息化时代&#xff0c;网络已成为人们生活和工作的基础设施&#xff0c;从在线购物、社交互动到企业运营、政府服务&#xff0c;无处不在的网络连接着全球各地的人们和组织。然而&#xff0c;网络的便捷性也带来了诸多安全风险&#xff0c;网络安全问题日益凸显&#xff0c;…

EasyCVR视频汇聚平台如何配置webrtc播放地址?

EasyCVR安防监控视频系统采用先进的网络传输技术&#xff0c;支持高清视频的接入和传输&#xff0c;能够满足大规模、高并发的远程监控需求。平台支持多协议接入&#xff0c;能将接入到视频流转码为多格式进行分发&#xff0c;包括RTMP、RTSP、HTTP-FLV、WebSocket-FLV、HLS、W…