【C++】19.红黑树模拟实现 set 和 map

我们想要实现STL中的set和map,那么第一步就需要看一下库函数是如何实现的:
在这里插入图片描述
通过查看源代码我们发现两个容器都包含了stl_tree.h,因此我们猜测此头文件实现的是红黑树。
但是set和map很显然不是使用同一棵树实现的,那么STL库是怎么解决这个问题的呢?

我们发现在构造红黑树的value时map使用的是pair<Key,T>,而set使用的则是Key

在这里插入图片描述

但是为什么在rb_tree类的构造时,要传四个参数呢?
我们知道Value是数据域,那么为什么还有传递Key呢?这难道不是重复了吗?
剩下的两个参数又代表着什么意思呢?
接下来我们的任务就是解决上述的问题。

一、set 和 map 的插入

首先value在插入时非常完美,但是在查找和删除时我们又应如何操作呢?set实现时,可以通过Value来进行操作,但是map实现时,我们有应如何操作呢?提取first元素吗?这样的话传递一个Key类型来方便操作。
接下来我们来实现一下插入部分发现:

if (kv < cur->_kv)
{parent = cur;cur = cur->_left;
}

当我们进行到比较操作的修改时,这个数据如何比较呢?
set的话我们当然可以直接比较,但是map呢?
在这里插入图片描述
通过查阅我们发现不是仅仅按first比较,因此我们需要定义方法来解决这个问题。
我们如何按照我们所预想的情景比较呢?
这样的话我们可以定义一个类来取得想要比较的元素
在这里插入图片描述
因此插入部分代码修改如下:

bool Insert(const V& v)
{//根节点为空,那此时插入的节点就是新节点if (_root == nullptr){_root = new Node(v);_root->_col = Black;return true;}KeyOfV kov;//提取key//此时根节点不为空//开始找应该插入的位置Node* cur = _root;Node* parent = cur->_parent;while (cur){if (kov(v) <kov( cur->_v)){parent = cur;cur = cur->_left;}else if (kov(v) >kov( cur->_v)){parent = cur;cur = cur->_right;}elsereturn false;//相等就表示已经存在了}//插入新节点cur = new Node(v);if (kov(v)<kov( parent->_v))parent->_left = cur;elseparent->_right = cur;cur->_parent = parent;//红色才修改while (parent&&parent->_col == Red){//取得g节点和u节点Node* grandfather = parent->_parent;Node* uncle = nullptr;//父节点此时为左孩子if (parent == grandfather->_left){uncle = grandfather->_right;}//父节点此时为右孩子else{uncle = grandfather->_left;}//u节点为红色if (uncle && uncle->_col == Red){parent->_col = uncle->_col = Black;grandfather->_col = Red;cur = grandfather;parent = cur->_parent;}//u节点不存在或u节点为黑色else{//父节点是g的左孩子if (parent == grandfather->_left){//cur是父节点的左孩子if (cur == parent->_left){RotateR(grandfather);parent->_col = Black;grandfather->_col = Red;}//cur是父节点的右孩子else{RotateLR(grandfather);cur->_col = Black;grandfather->_col = Red;}break;//调整完此时一定ok}//父节点是g的右孩子else{//cur是父节点的左孩子if (cur == parent->_left){RotateRL(grandfather);cur->_col = Black;grandfather->_col = Red;}//cur是父节点的右孩子else{RotateL(grandfather);parent->_col = Black;grandfather->_col = Red;}break;}}}_root->_col = Black;return true;
}

二、set 和 map 迭代器实现遍历

我们通过查看源代码发现,map和set底层都是通过调用红黑树的迭代器来完成遍历的:
在这里插入图片描述
那么此时我们只需要关注红黑树的迭代器是怎么实现的即可。
在这里插入图片描述
而底层的红黑树实现是利用头结点:
在这里插入图片描述
我们没有设置头节点,因此在这里简单实现一下:

//红黑树迭代器
template<class V,class Ref,class Ptr>
struct RBTreeIterator
{typedef typename RBTreeNode<V>	Node;//节点typedef typename RBTreeIterator<V, Ref, Ptr> Self;Node* _node;Node* _root;RBTreeIterator(Node* node,Node* root) :_node(node),_root(root){}//++_nodeSelf& operator++(){Node* cur = _node;if (cur->_right ){Node* LeftMost = cur->_right;while (LeftMost->_left){LeftMost = LeftMost->_left;}_node = LeftMost;}else{Node* parent = cur->_parent;while (parent && parent->_right == cur){cur = parent;parent = cur->_parent;}_node = parent;}return *this;}//--_nodeSelf& operator--(){if (_node == nullptr){Node* RightMost = _root;while (RightMost->_right){RightMost = RightMost->_right;}_node = RightMost;}else{Node* cur = _node;if (cur->_left){Node* RightMost = cur->_left;while (RightMost->_right){RightMost = RightMost->_right;}_node = RightMost;}else{Node* parent = cur->_parent;while (parent && parent->_left == cur){cur = parent;parent = cur->_parent;}_node = parent;}}return *this;}Ref  operator*(){return _node->_v;}Ptr operator->(){return &_node->_v;}bool operator!=(const Self& s){return _node != s._node;}bool operator==(const Self& s){return _node == s._node;}
};

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

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

相关文章

vue3 Axios封装使用

先安装axios&#xff1a; npm install axios 第一步&#xff1a;项目src下创建一个名为request的文件夹&#xff08;看一下示例图&#xff09;&#xff1a; 然后在request下创建两个api.ts和index.ts的文件 api.ts里的内容&#xff1a;&#xff08;url写你自己的接口&#xff…

Vscode——如何快速搜索项目工程中的某个文件的位置

第一步&#xff1a;按 shift ctrl p 第二步&#xff1a;然后把 > 删除 第三步&#xff1a;输入文件名称即可

飞书群聊机器人自定义机器人接入,并实现艾特@群成员功能

飞书群聊机器人还是比钉钉的要麻烦一点&#xff0c;钉钉的直接通过手机号就可以艾特群里面的人&#xff0c;但是飞书的要想艾特群里面的人&#xff0c;需要使用用户的 Open ID 或 User ID。这两个ID怎么获取呢&#xff1f;还需要在飞书的开放平台上创建一个应用&#xff0c;然后…

《Java初阶数据结构》----6.<优先级队列之PriorityQueue底层:堆>

前言 大家好&#xff0c;我目前在学习java。之前也学了一段时间&#xff0c;但是没有发布博客。时间过的真的很快。我会利用好这个暑假&#xff0c;来复习之前学过的内容&#xff0c;并整理好之前写过的博客进行发布。如果博客中有错误或者没有读懂的地方。热烈欢迎大家在评论区…

使用FileZilla Cilent快速让手机与电脑进行文件互传(无需生态)

目录 前言使用 FileZilla笔者的话 前言 当设备多的时候文件的传输就成了一种问题。 就比如说我想将手机上的文件传到电脑里面&#xff0c;因为我使用的电脑跟我的手机不是一个生态的&#xff0c;它们唯一的联系或许就是连接到了统一 WIFI 下&#xff0c;也就是说它们在同一个…

【React】全面解析:从基础知识到高级应用,掌握现代Web开发利器

文章目录 一、React 的基础知识1. 什么是 React&#xff1f;2. React 的基本概念3. 基本示例 二、React 的进阶概念1. 状态&#xff08;State&#xff09;和属性&#xff08;Props&#xff09;2. 生命周期方法&#xff08;Lifecycle Methods&#xff09;3. 钩子&#xff08;Hoo…

计算存储背景与发展

随着云计算、企业级应用以及物联网领域的飞速发展&#xff0c;当前的数据处理需求正以前所未有的规模增长&#xff0c;以满足存储行业不断变化的需求。这种增长导致网络带宽压力增大&#xff0c;并对主机计算资源&#xff08;如内存和CPU&#xff09;造成极大负担&#xff0c;进…

TikTok养号的网络环境及相关代理IP知识

TikTok作为一个流行的短视频分享平台&#xff0c;其用户量非常庞大&#xff0c;很多商家和个人都会使用TikTok来进行引流和推广。由于TikTok的规则和政策限制了每个用户每天发布视频的数量&#xff0c;因此许多用户会使用多个账号来发布更多的视频以提高曝光率。 然而&#xff…

Oracle中LISTAGG 函数的介绍以及使用详情

LISTAGG 函数介绍 listagg 函数是 Oracle 11.2 推出的新特性。 其主要功能类似于 wmsys.wm_concat 函数&#xff0c; 即将数据分组后&#xff0c; 把指定列的数据再通过指定符号合并。 LISTAGG 使用 listagg 函数有两个参数&#xff1a; 1、 要合并的列名 2、…

一种多策略改进鹅智能优化算法IGOOSE(2024年新出优化算法) 种群初始化精英反向策略+非线性下降因子+黄金正弦变异策略

一种多策略改进鹅智能优化算法IGOOSE&#xff08;2024年新出优化算法&#xff09; 种群初始化精英反向策略非线性下降因子黄金正弦变异策略 文章目录 前言一种多策略改进鹅智能优化算法IGOOSE&#xff08;2024年新出优化算法&#xff09; 种群初始化精英反向策略非线性下降因子…

游泳耳机品牌哪个牌子好?四大高热度游泳耳机综合分析

近年来&#xff0c;游泳耳机的受欢迎程度呈指数级增长&#xff0c;市场热度不断攀升。但作为一名长期关注运动科技的专业人士&#xff0c;我必须提醒大家&#xff0c;在享受水下音乐的同时&#xff0c;也要注意选择专业可靠的产品。市面上许多所谓的“游泳耳机”其实缺乏必要的…

【C++】:红黑树深度剖析 --- 手撕红黑树!

目录 前言一&#xff0c;红黑树的概念二&#xff0c;红黑树的性质三&#xff0c;红黑树节点的定义四&#xff0c;红黑树的插入操作4.1 第一步4.2 第二步4.3 插入操作的完整代码 五&#xff0c;红黑树的验证六&#xff0c;实现红黑树的完整代码五&#xff0c;红黑树与AVL树的比较…

python实现盲反卷积算法

python实现盲反卷积算法 盲反卷积算法算法原理算法实现Python实现详细解释优缺点应用领域盲反卷积算法 盲反卷积算法是一种图像复原技术,用于在没有先验知识或仅有有限信息的情况下,估计模糊图像的原始清晰图像和点扩散函数(PSF)。盲反卷积在摄影、医学成像、天文学等领域…

前端数据可视化适配方案汇总

前端数据可视化适配方案汇总 1、前言2、方案一&#xff1a;vw vh2.1 实现效果2.2 实现思路2.3 实现代码2.3.1 css 方案2.3.1.1 sass2.3.1.2 less 2.3.2 js方案2.3.3 图表字体、间距、位移等尺寸自适应 3、scale3.1 实现效果3.2 实现思路3.3 实现代码 4、rem方案4.1 实现思路4.2…

2024暑假友谊赛 2

Problem - 1150B - Codeforces 小C是重度强迫症晚期患者&#xff0c;如果某些图形无法按照他的想法排列&#xff0c;那么他就会迎来他的末日。某天小C来到了心心念念的女神家里&#xff08;绝对不可能是女装大佬&#xff0c;绝对不可能&#xff09;&#xff0c;他发现地砖有两…

【漏洞复现】E-Cology OA——WorkflowServiceXml——SQL注入

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 E-Cology OA协同商务系统是一款面向中大型组织的数字化办公产品…

Mysql数据库第四次作业

mysql> create table student(sno int primary key auto_increment,sname varchar(30) not null unique,Ssex varchar(2) check (Ssex男 or Ssex女) not null,Sage int not null,Sdept varchar(10) default计算机 not null); mysql> create table Course(Con int primar…

昇思MindSpore学习入门-高阶自动微分

mindspore.ops模块提供的grad和value_and_grad接口可以生成网络模型的梯度。grad计算网络梯度&#xff0c;value_and_grad同时计算网络的正向输出和梯度。本文主要介绍如何使用grad接口的主要功能&#xff0c;包括一阶、二阶求导&#xff0c;单独对输入或网络权重求导&#xff…

7.24 模拟赛总结 [dp 专场] + tarjan

复盘 7:40 开题 看 T1 &#xff0c;妈呀&#xff0c;一上来就数数&#xff1f;盯了几分钟后发现会了&#xff0c;不就是 LCS 计数嘛 继续看&#xff0c;T2 看上去很恶心&#xff0c;线段覆盖&#xff0c;感觉可能是贪心什么的 再看 T3&#xff0c;先想了个 n 2 n^2 n2 的式…

Vue 3 + Vite 项目中安装 Tailwind CSS

官网&#xff1a;安装 - TailwindCSS中文文档 | TailwindCSS中文网 tips&#xff1a;只按照官网的配置可能会导致样式不加载/加载不生效的问题 1、正确安装指令 npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p 自动生成 ​tailwind.config.js​…