【C++进阶篇】二叉搜索数

目录

前言:

以后我们要学map,set,AVL,红黑数所以必须要有二叉搜索数做铺垫

1、二叉搜索树概念

2.二叉搜索树操作

1.二叉搜索树的查找

a、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。

2. 二叉搜索树的插入

3.1  二叉搜索树的删除(一)

3.2  二叉搜索树的删除(二)

4. 二叉搜索树的应用


前言:
以后我们要学map,set,AVL,红黑数所以必须要有二叉搜索数做铺垫

1、二叉搜索树概念

  •  二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树。
  • 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值。
  • 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值。
  • 它的左右子树也分别为二叉搜索树。

2.二叉搜索树操作

1.二叉搜索树的查找
a、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。
b、最多查找高度次,走到到空,还没找到,这个值不存在。
	Node* Find(const K& key)  //查找{Node* cur = _root;while (cur){if (key > cur->_key){cur = cur->_right;}else if (key < cur->_key){cur = cur->_left;}else{return cur;}}return cur;}

2. 二叉搜索树的插入

插入的具体过程如下:
a. 树为空,则直接新增节点,赋值给 root 指针
b. 树不空,按二叉搜索树性质查找插入位置,插入新节点
注意:
二叉搜索树中不能出现值相同的节点,若插入时出现值相同的节点就直接返回false,插入失败!
bool insert(const K& key)//左小右大
{if (_root == nullptr)//第一次插入时的操作  //空树直接插入{_root = new Node(key);return true;}//不是空树找到要寻找的位置插入Node* cur = _root;Node* prev = nullptr;      //记录cur走过的上一个节点while (cur != nullptr){if (cur->_key < key){prev = cur;cur = cur->_right;}	else if (cur->_key > key){prev = cur;cur = cur->_left;}else if (cur->_key == key)return false;}cur = new Node(key);if (prev->_key > key)    //把cur节点和父节点连接起来prev->_left = cur;elseprev->_right = cur;return true;
}

3.1  二叉搜索树的删除(一)

首先查找元素是否在二叉搜索树中,如果不存在,则返回 , 否则要删除的结点可能分下面四种情
况:
a. 要删除的结点无孩子结点:直接删除就可以
b. 要删除的结点只有左孩子结点:删除此节点后,将此节点直接连接到父亲节点就可以
c. 要删除的结点只有右孩子结点:也是直接删除,然后直接把节点连接到父节点上
d. 要删除的结点有左、右孩子结点:这个我们在下面分析
bool erase(const K& key)//非递归版本
{
Node* prev = nullptr;
Node* cur = _root;
while (cur != nullptr)//先找到此节点再删除
{if (cur->_key < key){prev = cur;cur = cur->_right;}else if (cur->_key > key){prev = cur;cur = cur->_left;}else//找到了此节点后,开始删除{//1. 左边为空//2. 右边为空//3. 左右都不为空if (cur->_left == nullptr)//左孩子为空情况{if (cur == _root)_root = cur->_right;else{if (cur == prev->_left)prev->_left = cur->_right;elseprev->_right = cur->_right;}delete cur;return true;}else if (cur->_right == nullptr)//右孩子为空情况{if (cur == _root)_root = cur->_left;else{if (cur == prev->_left)prev->_left = cur->_left;elseprev->_right = cur->_left;}delete cur;return true;}
}

3.2  二叉搜索树的删除(二)

要删除的结点有左、右孩子结点
这里我们要找到这个节点的右子树的最小节点,把他替换要删除的节点上,然后在删除这个最小的节点,因为最小节点肯定没有左子节点(如果有,他就不是最小节点)
//注,此时的cur即为要删除的节点
Node* tmp = cur->_right;
Node* prevtmp = cur;
while (1) //寻找右子树中的最左节点
{if (tmp->_left != nullptr){prevtmp = tmp;tmp = tmp->_left;}elsebreak;
}
cur->_key = tmp->_key;
if (tmp->_right == nullptr)//如果被替换的节点的右为空
{if (prevtmp == cur)//被删除节点右边只有一个节点,直接将被删除节点的右置空prevtmp->_right = nullptr;elseprevtmp->_left = nullptr;delete tmp;tmp = nullptr;
}
else
{if (prevtmp == cur)prevtmp->_right = tmp->_right;elseprevtmp->_left = tmp->_right;delete tmp;tmp = nullptr;
}

4. 二叉搜索树的应用

1. K 模型: K 模型即只有 key 作为关键码,结构中只需要存储 Key 即可,关键码即为需要搜索到
的值
比如: 给一个单词 word ,判断该单词是否拼写正确 ,具体方式如下:
  • 以词库中所有单词集合中的每个单词作为key,构建一棵二叉搜索树
  • 在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误
void TestBSTree()
{BSTree<std::string, std::string> dict;dict.Insert("sort", "排序");dict.Insert("string", "字符串");dict.Insert("tree", "树");dict.Insert("vector", "顺序表");std::string str;while (std::cin >> str){BSTreeNode<std::string, std::string>* ret = dict.Find(str);  //节点的指针if (ret){std::cout << ret->_value << std::endl;}else{std::cout << "没有这个单词" << std::endl;}}
}
2. KV 模型:每一个关键码 key ,都有与之对应的值 Value ,即 <Key, Value> 的键值对 。该种方
式在现实生活中非常常见:
  • 比如英汉词典就是英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英
        文单词与其对应的中文<word, chinese> 就构成一种键值对;
  • 再比如统计单词次数,统计成功后,给定单词就可快速找到其出现的次数,单词与其出
        现次数就是<word, count> 就构成一种键值对
void TestBSTree()
{std::string strArr[] = { "西瓜", "菠萝", "哈密瓜", "香蕉", "苹果", "西瓜", "西瓜", "西瓜", "西瓜", "西瓜", "西瓜", "樱桃" };BSTree<std::string, int>countTree;for (auto e: strArr){BSTreeNode<std::string, int>* ret = countTree.Find(e);{if (ret == nullptr){countTree.Insert(e, 1);}else{ret->_value++;}}}countTree.InOrder();
}


以上就是今天的内容分享感谢各位的收看!!!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/216570.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jmeter 压测保姆级入门教程

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

Synchronized 优化

目录 前言 重点 一、 轻量级锁 二、锁膨胀 三、重量锁 四、偏向锁 五、其他优化 我的其他博客 前言 Java synchronized 是一种机制&#xff0c;可以保证多个线程在访问共享资源时的同步性。synchronized 关键字可以用于方法或代码块上&#xff0c;当一个线程获取了这个对…

消息中间件比较

那都有哪些中间件可供选择呢。其实现在主流的消息中间件就4种&#xff1a;kafka、ActiveMQ、RocketMQ、RabbitMQ 下面我们来看一下&#xff0c;他们之间有什么区别&#xff0c;他们分别应该用于什么场景 ActiveMQ 我们先看ActiveMQ。其实一般早些的项目需要引入消息中间件&…

Java笔记草稿——已完成

导航&#xff1a; 【Java笔记踩坑汇总】Java基础JavaWebSSMSpringBootSpringCloud瑞吉外卖/黑马旅游/谷粒商城/学成在线设计模式面试题汇总性能调优/架构设计源码-CSDN博客 推荐学习视频&#xff1a; 黑马程序员全套Java教程_哔哩哔哩 尚硅谷Java入门视频教程_哔哩哔哩 目录 零…

Unity_ET框架项目-斗地主_启动运行流程

unity_ET框架项目-斗地主_启动运行流程 项目源码地址&#xff1a; Viagi/LandlordsCore: ET斗地主Demohttps://github.com/Viagi/LandlordsCore下载项目到本地。 启动运行步骤&#xff1a; 下载目录如下&#xff1a; 1. VS&#xff08;我用是2022版VisualStudio&#xff09…

快速上手linux | 一文秒懂Linux各种常用目录命令(上)

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 一 、命令提示符和命令的基本格式1.1 如何查看主机名称及修改 二、命令基本格式2.1 命令格式示例2.2 参数的作用…

C# WebSocket简单使用

文章目录 前言Fleck调试工具初始化简单使用 前言 最近接到了一个需求&#xff0c;需要网页实现上位机的功能。那就对数据传输的实时性要求很高。那就只能用WebSocket了。这里简单说一下我的WebSocket如何搭建 Fleck C# WebSocket(Fleck) 客户端:html Winfrom Fleck Github官网…

Kafka集成springboot

安装kafka&#xff0c;直接到官网下载bin文件&#xff0c;本文使用windows进行使用kafka。 下载之后&#xff0c;第一步&#xff0c;启动zookeeper&#xff1a; zookeeper-server-start.bat ..\..\config\zookeeper.properties 第二步&#xff0c;启动kafka&#xff1a; kafka…

对比SPI、UART、I2C通信的区别与应用

SPI、UART、I2C通信是常用的数字通信协议&#xff0c;它们在不同的场景下有不同的应用。下面&#xff0c;我将分别介绍它们的特点、区别与应用。 SPI通信 SPI通信是一种串行同步通信协议&#xff0c;它的全称为“Serial Peripheral Interface”。SPI通信是一种单主多从的通信方…

你都那么老了,还在每天写博客吗?

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 白色便民网&#xff1a;我想多开一个公司会不会被税局查? 事件背景&#xff1a; 松松已创业9年&#xff0c;自媒体14年&#xff0c;经历过从0开公司、项目失败、赚钱等各种高光时刻。所以对于小微企业经营还是…

程序中关于时间和比较运算符的单词

时间 在日志中&#xff0c;我们经常碰到关于一些时间的单词缩写 比如这个Fri Dec 1 就代表了Friday &#xff08;星期五&#xff09;&#xff0c; December &#xff08;十二月&#xff09; 12月1日星期五 或者使用date查看时间的时候 dateWed Dec 13 05:55:54 PM CST 2023这…

OfficeWeb365 SaveDraw 文件上传漏洞复现

0x01 产品简介 OfficeWeb365 是专注于 Office 文档在线预览及PDF文档在线预览云服务,包括 Microsoft Word 文档在线预览、Excel 表格在线预览、Powerpoint 演示文档在线预览,WPS 文字处理、WPS 表格、WPS 演示及 Adobe PDF 文档在线预览。 0x02 漏洞概述 OfficeWeb365 Sav…

Win10 安装.NET Framework 3.5 报错0x80240438

环境&#xff1a; Win10专业版 NET Framework 3.5 问题描述&#xff1a; Win10 安装.NET Framework 3.5 报错0x80240438 解决方案&#xff1a; 1.检查自动更新服务是否未开启&#xff0c;开启自动更新失败&#xff0c;用工具开启自动更新,重启电脑&#xff08;未解决&am…

Proxmox创建Windows虚拟机

文章目录 下载ISO安装文件上传 下载ISO安装文件 下载地址&#xff1a;https://www.xitongzhijia.net/ 也可去官网进行下载 上传 将下载的ISO文件上传到Proxmox 选择ISO文件进行上传 上传后再ISO镜像中可以看到安装文件 点击创建虚拟机 填写名称&#xff0c;不能填写中文 镜…

团建策划信息展示服务预约小程序效果如何

团建是中大型企业商家每年举办的员工活动&#xff0c;其形式多样化、具备全部参与的娱乐性。但在实际策划流程及内容时&#xff0c;部分公司便会难以入手&#xff0c;术业有专攻&#xff0c;这个时候团建策划公司便会发挥效果。 如拓展训练、露营、运动会、体育竞技等往往更具…

[Linux] 基于LAMP架构安装论坛

一、安装Discuz论坛 1.1 创建数据库&#xff0c;并进行授权 mysql -u root -p123CREATE DATABASE bbs; #创建一个数据库GRANT all ON bbs.* TO bbsuser% IDENTIFIED BY admin123; #把bbs数据库里面所有表的权限授予给bbsuser,并设置密码admin123flush privileges; #刷新数据库…

Linux系统调试课:I2C tools调试工具

文章目录 一、如何使用I2C tools测试I2C外设1、I2C tools概述: 2、下载I2C tools源码:3、编译I2C tools源码: 4、i2cdetect 5、i2cget 6、i2cdump

docker基本管理和相关概念

docker是什么&#xff1f; docker是开源的应用容器引擎。基于go语言开发的。运行在Linux系统当中开源轻量级的“虚拟机”。 docker的容器技术可以在一台主机上轻松的为任何应用创建一个轻量级的&#xff0c;可移植的&#xff0c;自给自足的容器。 docker的宿主机是Linux系统…

天池SQL训练营(四)-集合运算-表的加减法和join等

-天池龙珠计划SQL训练营 4.1表的加减法 4.1.1 什么是集合运算 集合在数学领域表示“各种各样的事物的总和”, 在数据库领域表示记录的集合. 具体来说,表、视图和查询的执行结果都是记录的集合, 其中的元素为表或者查询结果中的每一行。 在标准 SQL 中, 分别对检索结果使用 U…

Spring Cloud gateway - CircuitBreaker GatewayFilte

前面学习Spring cloud gateway的时候&#xff0c;做测试的过程中我们发现&#xff0c;Spring Cloud Gateway不需要做多少配置就可以使用Spring Cloud LoadBalance的功能&#xff0c;比如&#xff1a; spring:application:name: spring-gatewaycloud:gateway:routes:- id: path…