首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【C++高阶】探索STL瑰宝 map与set:高效数据结构奥秘与技巧

无论是在算法竞赛中,还是在日常编程中,它们都是不可或缺工具 我们将从map和set定义和特性开始,介绍它们基本用法和常用成员函数。接着,我们将通过示例代码,展示如何在实际编程中使用它们。...set set s2(v.begin(),v.end()); set s3(s2); // set拷贝构造 return 0; } set迭代 set迭代有点多...返回set最后一个元素下一个位置反向const迭代,即crbegin 因而有迭代存在,set可以跟方便遍历整个结构 迭代实现(示例): int main() { vector...而set则以其独特元素唯一性特点,为我们提供了一种确保集合中元素不重复方法,然而学习之路永无止境。对于map和set理解和应用,仅仅停留在基本使用层面是远远不够。...我们需要进一步探索它们高级用法 学习STL中容器并不仅仅是为了掌握它们使用方法。更重要是,我们要学会如何根据问题需求选择合适容器类型,以及如何优化我们代码以提高程序性能和可维护性。

14510

关联式容器set和map

---- 关于pair pair是一个struct模板类,里面有两个成员,通常我们将first认为是key而second认为是value,但它们类型具体是什么则由我们自己决定,,一般我们pair...KV结构可以解决更多问题 2.lower_bound&&upper_bound lower_bound返回大于等于目标值迭代,upper_bound返回大于目标值迭代,在set中用于返回目标值迭代...(可以将获取到两个迭代作为一个迭代区间用于删除或插入) 可以看到这个erase将2和3都给删掉了,可以理解为删除是一个这样区间:[2,3] 3.find和count find find...insert 在之前搜索树和set中因为不允许键值冗余所以插入返回值就是一个bool值,这里却给了一个迭代,文档中对返回值这样说:如果不存在这个元素,那么返回迭代是新插入元素迭代...不存在就插入在返回迭代 2.根据迭代获取pairfirst,再由first获取到second 3.因为operator[]只给了key,因此value(ret.first->second;)给是默认值

18920
您找到你想要的搜索结果了吗?
是的
没有找到

【C++】map、set、multimap、multiset介绍和使用

在使用set迭代进行遍历时,set迭代是中序遍历顺序,每一个迭代都指向对应位置键值对,当然set容器元素我们也可以叫做键值对,只不过key和value相等罢了。 6....map中比较时比较是key类型,但我们可以通过key找到value,这里多说一句,无论是map还是set,他们迭代都是中序顺序。 2.2 map使用 1....对于map来说,*it拿到pair对象,所以我们还需要再加一个.操作符才能访问pair对象里面的first和second值,但这样写起来有点麻烦,所以map迭代也重载了→操作符,→重载函数会返回迭代指向对象地址...然后我们将键值对利用sort来进行排序,但由于map迭代是双向迭代,而sort要求支持随机访问,因为他底层是快排,那就需要随机迭代,所以我们将map中键值对语法糖式尾插到vector里面,vector...这道题目就比较简单了,我们可以利用set先进行排序+去重,然后比较两个set里面的值,如果两个值相等时,说明这个值是两个数组交集,两个迭代同时往后走,去后面继续比较,如果不相等,那就让较小元素对应迭代往后

64630

【C++】红黑树封装实现 map 和 set

和 map 插入删除查找等各种功能都是封装复用红黑树接口,对于 map来说,key_type 就是我们平常所理解 K,但是 value_type 却是 pair 类型,它两个参数分别是模板参数...在明白了 stl 源码是如何解决 set K模型 和 map KV模型 问题后,我们就可以参照它做法将我们自己实现红黑树改造一下: //节点颜色 enum Color { RED, BLACK...红黑树迭代和 list 迭代不同地方在于红黑树 end() 迭代位置以及迭代如何进行 ++ 与 –; end() 迭代位置 STL 明确规定,begin() 与 end() 代表是一段前闭后开区间...set 模拟实现前面部分很简单,在类中定义一个 RBTree 类型成员变量,然后插入、查找等函数都直接调用红黑树对应函数即可;set 模拟实现重难点在于 set 迭代实现; 我们可以直接将红黑树迭代封装为...--红黑树const迭代就是set普通迭代 return std::pair(p.first, p.second); } 至此,我们使用红黑树来封装 set

80430

再探 setmap

map篇 放码过来 map迭代 自定义排序 [] 运算符重载函数 C++map迭代++操作是如何实现?...---- set迭代 set迭代都是const,因此无法通过迭代修改set元素。 正常,人家迭代是主键,要用来排序。你可以删,但不可以改。...,并返回指向该元素迭代 s.upper_bound(x)表示查找>x元素中最小一个,并返回指向该元素迭代 举个例子: 在set{3,5,7,8,13,16}中 对于在set中存在元素,比如...8 s.lower_bound(8)返回8所在位置迭代 s.upper_bound(8)返回13所在位置迭代 对于在set中不存在元素,比如12 两个函数返回则都是13所在位置迭代 特殊地...---- C++map迭代++操作是如何实现? ++操作就是中序遍历。 但是别看遍历一次二叉树复杂度是O(N),一旦拿二叉树遍历跟vector遍历来比较,性能就大大降低了。

66520

C++【一棵红黑树封装 set 和 map】

---- 前言 红黑树基本情况我们已经在上一篇文章中学习过了,本文主要研究是红黑树实际应用:封装实现 set 和 map,看看如何通过一棵红黑树满足两个不同数据结构;在正式封装之前,先要对之前红黑树进行完善...((*this) == it); //复用 } 注意: 是迭代迭代比较,所以参数是 Self 即迭代对象 1.2.5、迭代测试 有了这些模块后,我们 红黑树 类中就可以引入 迭代 相关操作了..._node) //构造 或 拷贝构造 {} 如何做到?...---- 总结 以上就是本次关于 C++【一棵红黑树封装 set 和 map】全部内容了,在本文中,我们首先将 红黑树 进行了完善,解决了一些深拷贝问题,新增了迭代,同时还用反向迭代适配器适配出了...反向迭代,当红黑树完善后,我们用同一棵红黑树同时封装实现了 set 和 map,其中涉及大量 泛型编程思想,值得仔细推敲 ----

24130

C++:map和set使用

3.2.1 构造函数 1、空set 2、迭代区间构造(可以是其他容器迭代) 3、拷贝构造 3.2.2 迭代 有着和vector和list一样迭代,但是要注意是: (1)该迭代是一个双向迭代...我们来看看 pair 究竟代表了什么含义,我们前面说明了,set是不允许键值冗余,也就是说我们set可能会插入失败,如上图后两个1就是插入失败例子,bool就是为了区分插入成功还是失败...比如说1 2 3 4 5 8 9 10,如果我们想插入一个7,那么如果我们是5或者8迭代,此时就是一个高效插入(因为相邻),但是如果我们迭代是9,那么此时就不是一个高效插入,因为找到9...3、第三个参数是迭代区间,其实就是插入一个迭代区间返回(可以是其他容器迭代) 3.2.4 find find就是去set容器中找到对应键值并返回他对应迭代,如果找不到,就会返回end...(2)和之前set一样,参数传进去迭代相当于是一个暗示在该迭代附近,如果相邻的话,可以实现最高效率插入,如果不相邻的话就不存在。

8910

C++【set 和 map 学习及使用】

,默认为升序,即符合 二叉搜索树 中序遍历结果:升序,参数3 Alloc 是空间配置,现在不必深究 作为 STL 中容器,set 当然少不了迭代,树型关联式容器迭代遍历结果为有序,所以迭代遍历本质是...中序遍历,同时 set 迭代还是一个 双向迭代,支持 ++ 和 -- 操作 下面来看看 set 相关操作 2.2、set 使用 set 构造函数如下图所示: 可以直接创建一个空.../迭代遍历 cout << "迭代遍历结果: "; set::iterator it = s1.begin(); while (it !...,因此即使是 set普通迭代,本质上也是 const 迭代,非常神奇 2.3、set 特点 set 具有以下特点: set 还有一个亲兄弟:multiset,它允许数据冗余,即数据插入一定是成功...make_pair("B", 66)}; map m1(arr.begin(), arr.end()); //迭代遍历 cout << "迭代遍历结果: ";

24120

【C++修炼之路】18.map和set

二.set 2.1 set介绍 set底层为二叉搜索树,也就是上一节中所实现,不过在此之上,set作为容器来说,封装了和以前vector、list、deque相关迭代、运算符重载等,方便我们去进行一系列操作...set set ( const set& x); set拷贝构造 3.set迭代 对于set迭代,和之前vector、list相同,有正向迭代...、反向迭代、const迭代。...在文档中发现,有两个函数:lower_bound,upper_bound,这两个实际上也是迭代类型,传入只有一个参数,同样是左闭右开,传值之后可以标记对应位置: int main() { set...上面所标注就是map[]重载返回值,发现还有insert操作,所以我们应该先知道insert返回值: 发现insert返回类型为pair类型,看看文档是如何说明

70400

【C++】 使用红黑树模拟实现STL中map与set

可以按我们之前理解,map里面存就是一个pair(键值对)嘛,pairfirst对应key,second对应value。 但是它里面为什么value类型就是一个pair呢?...而map查找返回是整个pair迭代(其实还是结点里面元素迭代,map里面存就是pair嘛。)...然后大家可以看一下这个图理解一下 ,那这个问题我们就解决了 3.6 红黑树迭代实现 那接下来我们来实现一下迭代,实现好之后也可以测试一下我们上面插入之后到底对不对。...3.7 封装set和map迭代并测试 那红黑树迭代实现差不多了,我们就可以用它封装set和map迭代了。...我们可以看一下库里面是怎么解决: 先来看set里面的迭代 我们看到它里面的普通迭代和const迭代都是用红黑树const迭代

14010

【C++】从零开始map与set封装

map与set大多数情况是用来检索工具,我们底层使用红黑树来完成map与set封装。 进行封装之前,我们先来实现一个非常重要东西:迭代 2 红黑树迭代 迭代好处是可以方便遍历。...如果想要给红黑树增加迭代,需要考虑以前问题: 迭代框架如何实现,才能满足泛型编程需求??...实现了迭代接下来我们就来实现map与set封装 3 map与set封装 3.1 红黑树改进 我们先来看我们红黑树节点代码: // 节点结构体 template<class K, class...如果我们想实现set封装还要在写一份红黑树代码,因为set节点数据是K 。这样就太不优雅了! 为了更好实现map与set封装,我们来看STL源码里是如何实现吧!...4 总结 通过近一周学习,我们终于将map和set从零建立起来了,这里不仅需要二叉搜索树知识还需要AVL树和红黑树使用!!!甚至还需要对于模版更深理解!!!

12010

【c++】set和map使用

如果给定值在set中不存在,它将返回指向下一个更大元素迭代;如果给定值大于set任何元素,它将返回指向set末尾迭代。...换句话说,lower_bound 返回是指向set中第一个不小于(即大于等于)给定值元素迭代 用法示例: std::set s; s.insert(1); s.insert(3); s.insert...如果所有的元素都小于给定值,它将返回指向set末尾迭代。 upper_bound 返回是指向set中第一个大于给定值元素迭代。...它返回一个包含两个迭代 pair,这对迭代分别代表键等于给定键元素序列开始和结束 当在普通(非multi)容器中使用 equal_range 时,返回范围包含零个或一个元素。...,并返回一个包含两个迭代 pair,这些迭代标记着范围开始和结束。

3800

C++【哈希表完善及封装】

需要对 扩容 地方进行改造 在改造之后,哈希表 初始大小变为 53 1.4、新增:迭代类 哈希表 中理应提供一个 迭代 对其中值进行判断,因为 桶 是一个 单链表,只能向前走,不能回头,因此我们...} 在这个函数中,访问了 哈希表类 中私有成员 _table,这是不行,为了让其能成功访问,我们可以把 迭代类 设为 哈希表类 友元类 同时,在 哈希表类 中增加 迭代操作 相关函数 template...迭代非法操作 unordered_set 中只有 键值,而 键值 是不能被随意修改(通过迭代方式) void TestUS2() { vector arr = { 7,3,6,9,3,1,6,2...库中解决方法:不管你 unordered_set 申请是什么迭代,我都给你 const 迭代 //迭代 typedef typename HT::const_iterator iterator...这是因为 unordered_set 中 普通对象版 begin() 或 end() 使用是 哈希表中 const 迭代,但哈希表中迭代相关函数返回是 普通迭代 啊,也就是说,存在一个 普通迭代

27460

【C++】关联式容器——map和set使用

<< " "; cout << endl; } set迭代 函数声明 功能介绍 iterator begin() \end() 返回set中起始位置元素迭代\返回set中最后一个元素后面的迭代...const_iterator cbegin()\cend() const 返回set中起始位置元素const迭代\返回set中最后一个元素后面的const迭代 reverse_iterator...rbegin() \rend() 返回set第一个元素反向迭代,即end\返回set最后一个元素下一个位置反向迭代,即 rbegin const_reverse_iterator crbegin...() \crend() const 返回set第一个元素反向const迭代,即cend\返回set最后一个元素下一个位置反向const迭代, 即crbegin 我们简单来看一看代码把: void...; } 默认是升序,如果是想要降序:使用反向迭代 仿函数:lessgreater: set修改操作 find&&erase 对于find和erase我们都是比较熟悉了,我们可以直接上手代码实现

22830

【C++修炼之路】21.红黑树封装map和set

一.改良红黑树数据域结构 对于如何设计针对map、set红黑树结构,看源码实现无疑是最好方式: 对于源码实现,我们知道set键值对,但是在使用时却只显示一个k,map是...迭代 需要将有关迭代功能都封装起来,这在之前vector、list模拟实现时已经了解过。对于map和set迭代,重要函数重载就是++和–了。...答案是行不通,因为对end()位置迭代进行–操作,必须要能找最后一个元素,此处就不行,因此最好方式是将end()放在头结点位置: 但由于我们上一届中设计RBTree没有头结点这个结构,因此我们也就不与...如果是const迭代,那可以在迭代类中多加上两个模板参数:T&, T*偏特化,当然实际上是Ref,Ptr全特化;由于set不能修改,因此set普通迭代和const迭代都应该是const类型...,但mapvalue可以修改,因此我们就需要在RBTree中把普通迭代和const迭代均实现出来。

30400

map和set简单介绍

为了方便大家理解我们在stl源码中提取了对于键值对定义: 我们从map官方解释中可以看到,键值对类型是 pair 源码中就是定义了pair结构体 在结构体...,除非用户不想使用标准库提供空间配置 注意:在使用map时,需要包含头文件,set也一样 map构造: map迭代: 关于迭代使用我们依旧用代码来了解,更容易理解 map...使用set迭代遍历set元素,可以得到有序序列 set元素默认按照小于来比较 set元素不允许修改 set底层使用二叉搜索树(红黑树)来实现。...= st.end(); i++) { cout << *i << endl; } return 0; 从本段代码输出结果来看就知道set去重效果了 我们可以用迭代来排出一个有序序列:...使用迭代对multiset中元素进行遍历,可以得到有序序列 multiset中元素不能修改 multiset作用:可以对元素进行排序 其实set和multiset区别就在于multiset

6010

【C++】使用哈希表模拟实现STL中unordered_set和unordered_map

哈希表迭代实现 接着我们来实现一下哈希表迭代 我们来思考一下它迭代应该怎么搞: 那按照我们以往经验,它迭代应该还是对结点指针封装,然后顺着每个不为空哈希桶(链表)进行遍历就行了。...然后end用空构造就行了 6. unordered_set和unordered_map迭代封装 那哈希表迭代实现好,我们就可以封装unordered_set和unordered_map迭代了...那unordered_set搞好了,unordered_map迭代我们也来封装一下: 来测试一下 没有问题。...,随意改散列就出问题了: 那我们来处理一下: 那其实解决方法和set那里是一样,库里面也是一样方法,让unordered_set迭代都是哈希表const迭代。...那首先我们得实现一下const迭代: 先得给哈希表实现一下,还是之前方法,通过增加两个模板参数 然后const版本begin和end: 那然后我们set迭代器重新封装一下: 然后再运行:

12010

【C++】map和set封装

data大小如何去进行比较:我们并不知道是什么类型是key,还是pair比较,而我们刚开始kv结构就直接用kv.first去比较了。...对于set是Key,可以比较 对于map是pair,那我们要取其中first来比较,但是pair大小并不是直接按照first去进行比较,而我们只需要按照first去进行比较 由于底层红黑树不知道传是...红黑树正向迭代是对结点指针进行了封装,所以这里正向迭代就只有一个成员变量:结点指针,并没有什么其他地方,迭代定义: template<class T,class Ref,class Ptr..._node; } 这里迭代器重点是迭代++: 一个结点正向迭代进行++操作后,根据红黑树中序(左、根、右)找到当前结点下一个结点,中序第一个节点是最左,迭代++怎么去找: 如果节点右子树不为空...);//用普通迭代构造const迭代 } private: RBTree _t; }; void test_set() { int a[] =

13420
领券