map和set基本使用

map和set基本使用

  • 二叉搜索树
  • set
  • multiset
  • map
  • multimap

二叉搜索树

在学习map和和set的使用之前,我们需要对二叉搜索树有一定的了解。
二叉搜索树也称二叉排序树或者二叉查找树,如果该树不是空树,就应该满足以下条件:非空左子树的所有键值都小于其根结点的键值,非空右子树的所有键值都大于其根结点的键值,且左右子树也都是二叉搜索树。

二叉搜索树的插入和查找逻辑都比较简单,这里不过多讨论,其结点的删除一般采用替换删除法,进行删除时分4种情况:
1.要删除的结点没有孩子
直接删除并将其父结点指向置空即可

2.要删除的结点只有左孩子
将其父结点的指向指向要删除的结点的左孩子后直接删除

3.要删除的结点只有右孩子
将其父结点的指向指向要删除的结点的右孩子后直接删除

4.要删除的结点有左孩子、右孩子
在要删除结点的左子树找到键值最大的结点L或在要删除结点的右子树找到键值最小的结点R,只需要将L或R的键值赋值给要删除的结点,然后删除L或R结点即可,因为L一定没有右孩子,R一定没有左孩子,所以L或R结点的删除一定属于1、2、3情况中的某一种。

由于删除除叶子结点时叶子结点既可以看成只有左孩子(左孩子为空)也可以看成只有右孩子(右孩子为空),所以可以将1、2或者1、3当作同一类情况来看。

二叉搜索树有两种模型:
1.K模型:即只有key作为关键码,结点只需要存储key即可,key就是我们需要的数据。

2.KV模型:每一个关键码key都对应一个只value,我们需要存储key和value,通过key去搜索结点时,value才是我们需要的数据。

使用二叉搜索树,其数据的插入、删除、查找成本都较低,是良好的数据结构,但当其变为单支时,查找效率会大大下降,从而导致插入和删除的效率也下降,由此改进就产生了平衡搜索二叉树,使进行结点插入删除时这棵树依然接近完全二叉树,经典的平衡搜索二叉树有AVL树和红黑树。

我们前面使用的vector、list等容器都是属于序列式容器,其底层为线性结构,里面存储的是元素本身,而关联式容器存储的是<key value>结构的键值对,在进行数据检索时效率比序列式容器高。我们下面介绍的map、multimap、set、multiset属于树形结构的关联式容器,其底层结构为红黑树。

在学习使用这些容器之前,我们先了解2个模板
1.pair
pair是一个类模板,包含在头文件<utility>中

template <class T1, class T2> struct pair;

在这里插入图片描述
这个类模板实例化后可以存储两个类型不同的数据,存放在公共成员变量first和second中,在类外可以直接访问,其构造函数如下:

pair();template<class U, class V> pair (const pair<U,V>& pr);pair (const first_type& a, const second_type& b);//
//Type of member first, aliased as first_type.//Type of member second, aliased as second_type.

2.make_pair
make_pair是一个函数模板,返回一个pair对象,包含在头文件<utility>中

template <class T1, class T2>pair<T1,T2> make_pair (T1 x, T2 y);

set

set在用户使用上看上去是K型搜索二叉树,只存放了key值,但在底层存放的是<key,key>构成的键值对,不过我们用户直接将其当成K型搜索二叉树即可,不需要构建键值对。需要注意的是,set的元素比较默认是按小于进行比较的,且不会插入重复元素,不能修改结点值。

template < class T,                        // set::key_type/value_typeclass Compare = less<T>,        // set::key_compare/value_compareclass Alloc = allocator<T>      // set::allocator_type> class set;

在这里插入图片描述
1.构造

explicit set (const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());template <class InputIterator>set (InputIterator first, InputIterator last,const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());set (const set& x);// InputIterator shall be an input iterator type that points to elements of a type from which value_type objects can be constructed.

2.赋值运算符重载

set& operator= (const set& x);

3.迭代器

//正向迭代器iterator begin();
const_iterator begin() const;iterator end();
const_iterator end() const;//反向迭代器reverse_iterator rbegin();
const_reverse_iterator rbegin() const;reverse_iterator rend();
const_reverse_iterator rend() const;

4.判断是否为空

bool empty() const;

5.获取结点个数

size_type size() const;

6.元素插入

pair<iterator,bool> insert (const value_type& val);
//如果元素是第一次插入,pair的first指向插入的结点,bool设为true
//如果相同key值已经存在,pair的first指向已经存在的结点,bool设为falseiterator insert (iterator position, const value_type& val);template <class InputIterator>void insert (InputIterator first, InputIterator last);

7.元素删除

void erase (iterator position);size_type erase (const value_type& val);void erase (iterator first, iterator last);

8.清空搜索树

void clear();

9.交换两颗树

void swap (set& x);

10.查找某个结点

iterator find (const value_type& val) const;

11.获取某一key值的结点个数

size_type count (const value_type& val) const;
//由于set相同key值的结点只存一个,所以只返回0或1

12.返回第一个大于等于key值的结点

iterator lower_bound (const value_type& val) const;

13.返回第一个大于key值的结点

iterator upper_bound (const value_type& val) const;

multiset

multiset的元素允许重复,需要包含<set>头文件,multiset在底层存放的也是<key,key>构成的键值对,不过我们用户直接将其当成K型搜索二叉树即可,不需要构建键值对,其元素比较默认是按小于进行比较的,不能修改结点值。multiset容器的使用几乎与set一样,我们这里只看常用的有区别的接口。

1.插入

iterator insert (const value_type& val);
//返回结点的迭代器,不再是pairiterator insert (iterator position, const value_type& val);template <class InputIterator>void insert (InputIterator first, InputIterator last);

2.查找

iterator find (const value_type& val) const;
//如果存在重复元素,也只返回其中一个结点

3.返回key值的结点个数

size_type count (const value_type& val) const;
//不再只是返回0或1

map

map是一种KT型搜索二叉树,在底层存的是<key value>键值对元素比较默认是按小于进行比较的,可以修改value值,但不能修改key值,不允许元素重复(key值相等即为元素相等),如果元素插入时key值相等,但value值不同,不进行任何操作。

template < class Key,                                     // map::key_typeclass T,                                       // map::mapped_typeclass Compare = less<Key>,                     // map::key_compareclass Alloc = allocator<pair<const Key,T> >    // map::allocator_type> class map;

在这里插入图片描述
1.构造

explicit map (const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());template <class InputIterator>map (InputIterator first, InputIterator last,const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());map (const map& x);//c++11支持使用pair对象构造map对象

2.赋值运算符重载

 map& operator= (const map& x);//c++11支持使用pair对象进行赋值

3.迭代器

//正向迭代器iterator begin();
const_iterator begin() const;iterator end();
const_iterator end() const;//反向迭代器reverse_iterator rbegin();
const_reverse_iterator rbegin() const;reverse_iterator rend();
const_reverse_iterator rend() const;

4.判断是否为空

bool empty() const;

5.获取结点个数

size_type size() const;

6.插入

pair<iterator,bool> insert (const value_type& val);
//如果元素是第一次插入,pair的first指向插入的结点,bool设为true
//如果相同key值已经存在,pair的first指向已经存在的结点,bool设为falseiterator insert (iterator position, const value_type& val);template <class InputIterator>void insert (InputIterator first, InputIterator last);//c++11支持使用pair对象进行插入

7.删除

     void erase (iterator position);size_type erase (const key_type& k);void erase (iterator first, iterator last);

8.[]运算符重载

mapped_type& operator[] (const key_type& k);
//利用k值作为下标获取对应的value值的引用
//如果k为key值的结点不存在,会插入key=k,value=默认构造的键值对,然后返回value的引用
//其本质是这个:(*((this-insert(make_pair(k,mapped_type()))).first)).second

9.at下标访问

     mapped_type& at (const key_type& k);
const mapped_type& at (const key_type& k) const;
//找到匹配的k值,返回对应的引用,找不到就报错

10.查找某个结点

      iterator find (const key_type& k);
const_iterator find (const key_type& k) const;

11.获取某一key值的结点个数

size_type count (const value_type& val) const;
//由于set相同key值的结点只存一个,所以只返回0或1

12.返回第一个大于等于key值的结点

      iterator lower_bound (const key_type& k);
const_iterator lower_bound (const key_type& k) const

13.返回第一个大于key值的结点

      iterator upper_bound (const key_type& k);
const_iterator upper_bound (const key_type& k) const;

14.交换两颗树

void swap (map& x);

15.清空搜索树

void clear();

multimap

multimap的元素允许重复,需要包含<map>头文件,其元素比较默认是按小于进行比较的,不能修改结点值。multimap容器的使用几乎与map一样,我们这里只看常用的有区别的接口。
由于key值可以重复,所以multimat不支持[]下标访问和at下标访问
1.插入

iterator insert (const value_type& val);
//也是返回迭代器,不再是pair对象iterator insert (iterator position, const value_type& val);template <class InputIterator>void insert (InputIterator first, InputIterator last);

2.查找

      iterator find (const key_type& k);
const_iterator find (const key_type& k) const;
//如果存在重复元素,也只返回其中一个结点

3.返回key值的结点个数

size_type count (const value_type& val) const;
//也不再只是返回0或1

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

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

相关文章

2024.3.4

思维导图 作业1&#xff1a;广播 发送端&#xff1a; #include<myhead.h> int main(int argc, const char *argv[]) {//创建套接字int sfd socket(AF_INET,SOCK_DGRAM,0);if(sfd -1){perror("sockeet error");return -1;}//设置当前套接字允许广播属性int …

nvm安装和使用保姆级教程(详细)

一、 nvm是什么 &#xff1a; nvm全英文也叫node.js version management&#xff0c;是一个nodejs的版本管理工具。nvm和npm都是node.js版本管理工具&#xff0c;为了解决node.js各种版本存在不兼容现象可以通过它可以安装和切换不同版本的node.js。 二、卸载之前安装的node: …

pytorch(五)逻辑斯蒂回归

文章目录 模型损失函数代码和结果 逻辑斯蒂回归解决的事分类问题&#xff0c;分类输出的是类别的概率 模型 在线性模型中&#xff0c;通过 y w x b ywxb ywxb输出的是一个实数值&#xff0c;但是在分类问题中&#xff0c;输出的是类别的概率&#xff0c;所以需要一个函数&am…

社交媒体的未来图景:探索Facebook的数字化之旅

社交媒体已经成为现代社会不可或缺的一部分&#xff0c;其影响力已经深入到人们生活的方方面面。而在众多社交媒体平台中&#xff0c;Facebook无疑是其中的巨头&#xff0c;其数字化之旅更是引领着整个社交媒体行业的发展方向。本文将深入探讨社交媒体的未来图景&#xff0c;以…

稳定性建设

开篇 SLA&#xff08;service-level agreement&#xff0c;即 服务级别协议&#xff09;也称服务等级协议&#xff0c;经常被用来衡量服务稳定性指标。业界高可用的标准是按照系统宕机时间来衡量的&#xff0c;通常被称作“几个 9”&#xff0c;9 越多代表服务全年可用时间越长…

Linux运维工具-ywtool默认功能介绍

提示:工具下载链接在文章最后 目录 一.资源检查二.日志刷新三.工具升级四.linux运维工具ywtool介绍五.ywtool工具下载链接 一.资源检查 只要系统安装了ywtool工具,默认就会配置上"资源检查"的脚本资源检查脚本的执行时间:每天凌晨3点进行检查资源检查脚本的检查内容…

如何使用公网地址远程访问内网Nacos UI界面查看注册服务

文章目录 1. Docker 运行Nacos2. 本地访问Nacos3. Linux安装Cpolar4. 配置Nacos UI界面公网地址5. 远程访问 Nacos UI界面6. 固定Nacos UI界面公网地址7. 固定地址访问Plik Nacos是阿里开放的一款中间件,也是一款服务注册中心&#xff0c;它主要提供三种功能&#xff1a;持久化…

Oracle 如何将txt文件中的数据导入数据库

使用文本导入器&#xff0c;可以将ASCII文件导入数据库。支持大多数面向行的格式&#xff0c;如逗号和制表符分隔的字段。导入程序将尝试自动确定文件格式&#xff0c;因此大多数时候您不会抰 需要定义任何内容&#xff0c;只需选择文件&#xff0c;选择一个表&#xff0c;然后…

三级分销数据库设计

一&#xff0c;数据结构 二&#xff0c;查询方法 1.mysql递归查询 获取id9的所有上级 r : 9 设置自己所要搜索子节点的id SELECTT2.* FROM(SELECTr AS _id,( SELECT r : pid FROM sj_user WHERE id _id ) AS 2v2,l : l 1 AS lvl FROM( SELECT r : 9 ) vars, -- 查询id为…

C语言 BMP图片的旋转与缩放

目录 一、bmp文件头、文件信息头、位图实际数据的数据结构定义 二、源BMP文件信息的读取 三、实际位图数据的旋转、缩放操作 四、生成转换过后的新位图文件 #include <stdlib.h> #ifndef PHOTODEAL_H #define PHOTODEAL_H #pragma pack(1) typedef struct tagBm…

基于React低代码平台开发:构建高效、灵活的应用新范式

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&…

Qt 实现橡皮擦拭显示图片

1.简介 在一些游戏中看见类似解密破案的效果&#xff0c;使用手触摸去擦拭图片上的灰尘&#xff0c;然后显示最终的图片&#xff0c;所以也想试试Qt实现的效果。大家有自己想做的效果&#xff0c;都可以尝试。 以下是效果展示图。 可以控制橡皮擦的大小&#xff0c;进行擦拭…