C++ STL底层实现

2023-05-16

文章目录

  • STL库的底层实现
    • array
    • vector
    • deque
    • list
    • forward_list
    • set、map
    • unordered_map、unordered_set
    • 迭代器

STL库的底层实现

  1. 顺序容器

    1. array数组
    2. vector向量
    3. deque双向队列
    4. list双向链表
    5. forward_list前向链表
  2. 关联容器

    1. map 关联数组key value
      1. map、multimap 排序实现
      2. unordered_map、unordered_multimap 哈希实现
    2. set 只保留关键子key
      1. set、multiset 排序实现
      2. unordered_set、unordered_multiset 哈希实现
  3. 容器适配器

    1. stack 栈
    2. queue 队列
    3. priority_queue 前向队列

各个容器的时间复杂度

操作访问,一般是指下标[n]访问,关联容器应该是用keypush_back()push_front()insert()pop_back()pop_front()erase()find()
顺序容器
list O ( n ) O(n) O(n) O ( 1 ) O(1) O(1) O ( 1 ) O(1) O(1) O ( 1 ) O(1) O(1),但是确定迭代器的位置需要 O ( n ) O(n) O(n) O ( 1 ) O(1) O(1) O ( 1 ) O(1) O(1) O ( 1 ) O(1) O(1)不支持
vector O ( 1 ) O(1) O(1) O ( 1 ) O(1) O(1)不支持 O ( n ) O(n) O(n) O ( 1 ) O(1) O(1)不支持 O ( n ) O(n) O(n)不支持
deque O ( 1 ) O(1) O(1) O ( 1 ) O(1) O(1) O ( 1 ) O(1) O(1) O ( n ) O(n) O(n) O ( 1 ) O(1) O(1) O ( 1 ) O(1) O(1) O ( n ) O(n) O(n)不支持
关联容器红黑树实现
map、multimap、set、multiset O ( l o g ( n ) ) O(log(n)) O(log(n))不支持不支持 O ( l o g ( n ) ) O(log(n)) O(log(n))不支持不支持 O ( l o g ( n ) ) O(log(n)) O(log(n)) O ( l o g ( n ) ) O(log(n)) O(log(n))
关联容器 hashtable实现
unordered_map、unordered_multimap、unordered_set、unordered_multiset O ( 1 ) O(1) O(1)不支持不支持 O ( 1 ) O(1) O(1)不支持不支持 O ( 1 ) ) O(1)) O(1)) O ( 1 ) ) O(1)) O(1))
最坏情况:出现哈希冲突时 O ( n ) O(n) O(n)不支持不支持 O ( n ) O(n) O(n)不支持不支持 O ( n ) ) O(n)) O(n)) O ( n ) ) O(n)) O(n))

哈希冲突的时间复杂度,不应该取决于hash的桶内用什么方式存储key value吗?

array

固定大小数组,支持快速随机访问,但不能插入或删除元素;

vector

vector底层是一个动态数组,包含三个迭代器,start和finish之间是已经被使用的空间范围,end_of_storage是整块连续空间包括备用空间的尾部。
连续空间,扩容机制,开辟新的内存(2倍),拷贝过去。进行扩容操作时可能导致迭代器失效。

支持下标访问。

vector<int> vec(10,100);        //创建10个元素,每个元素值为100

vec.resize(r,vector<int>(c,0)); //二维数组初始化

vec.reserve(100);               //改变vector的大小size()
vec.reserve(100);               //只改变vector的容量capacity()扩充到已经确定的大小

find(vec.begin(),vec.end(),1);  //查找元素
reverse(vec.begin(),vec.end())  //将元素翻转
sort(vec.begin(),vec.end());    //排序,默认升序排列
vec.push_back(val);             //尾部插入数字
vec.size();                     //向量大小
vec.capacity();                 //经分配的内存中可以容纳多少元素
iterator = vec.erase(iterator)  //删除元素

vec.clear();                    //清空内容,但是不释放内存。
vector<int>().swap(vec);        //清空内容,且释放内存,想得到一个全新的vector。
vec.shrink_to_fit();            //请求容器降低其capacity和size匹配。
vec.clear();vec.shrink_to_fit();//清空内容,且释放内存。

deque

双向开口的连续线性空间(双端队列)。一块内存前后都有空闲的空间用来存取。

支持头尾插入。

deque.push_back(elem)   //在尾部加入一个数据。
deque.pop_back()        //删除尾部数据。
deque.push_front(elem)  //在头部插入一个数据。
deque.pop_front()       //删除头部数据。
deque.size()            //返回容器中实际数据的个数。
deque.at(idx)           //传回索引idx所指的数据,如果idx越界,抛出out_of_range。

list

双向链表,非连续空间,用一块申请,删除也是以节点为单位。

方便大量插入。

list.push_back(elem)    //在尾部加入一个数据
list.pop_back()         //删除尾部数据
list.push_front(elem)   //在头部插入一个数据
list.pop_front()        //删除头部数据

auto it = list.begin();
list.insert(it, 10);    //需要使用迭代器在制定位置插入

list.size()             //返回容器中实际数据的个数
list.sort()             //排序,默认由小到大 
list.unique()           //移除数值相同的连续元素
list.back()             //取尾部迭代器
list.erase(iterator)    //删除一个元素,参数是迭代器,返回的是删除迭代器的下一个位置

forward_list

单向链表

set、map

红黑树,平衡、有序二叉树。红黑树介绍https://www.iamshuaidi.com/2061.html。key和value存储在节点中。插入与删除主要是调整节点的指针。
搜索 O ( l o g ( n ) ) O(log(n)) O(log(n))

//常用函数
map<int,string> mymap;
mymap.begin()                    //返回指向容器起始位置的迭代器(iterator) 
mymap.end()                      //返回指向容器末尾位置的迭代器 
bool bempty = mymap.empty()      //若容器为空,则返回true,否则false
mymap.find(k)                    //寻找键值为k的元素,并用返回其地址
int size = mymap.size()          //返回map中已存在元素的数量
mymap.insert({int,string})       //插入元素
for (auto iter = mymap.begin(); itor != mymap.end();++iter;)
{
    if (iter->second == "target")
        mymap.erase(itor++) ; // erase之后,令当前迭代器指向其后继。       
}


//几种不同的插入方式
map<int,string> ;
mapStudent.insert(pair<int, string>(1, "student_one")); 
mapStudent.insert(map<int, string>::value_type (1, "student_one"));
mapStudent.insert(make_pair(1, "student_one"));
mapStudent[1] = "student_one"; 

map[2]//下标方式访问,没有值会创建key value(默认值)的值插入

unordered_map、unordered_set

hashtable散列函数函数实现,通过哈希映射实现增删改查时间复杂度为 O ( 1 ) O(1) O(1)

unordered_map.begin()     //返回指向容器起始位置的迭代器(iterator) 
unordered_map.end()       //返回指向容器末尾位置的迭代器 
unordered_map.cbegin()     //返回指向容器起始位置的常迭代器(const_iterator) 
unordered_map.cend()      //返回指向容器末尾位置的常迭代器 
unordered_map.size()      //返回有效元素个数 
unordered_map.insert(key)  //插入元素 

myunordered_map[key];      //通过重载的[]访问,没有key时候会自动插入,并填充默认值
unordered_map.find(key)   //查找元素,返回迭代器
unordered_map.count(key)  //返回匹配给定主键的元素的个数 

迭代器

https://www.iamshuaidi.com/2328.html
底层实现 萃取技术(推导类型),模板特化技术具体实现。
迭代器失效 当存储数据的内存位置发生改变时。

顺序容器:删除迭代器it = c.erase(it);返回值下一个迭代器。因为除了list外,erase会导致当前迭代器失效,不能使用it++
关联容器:删除迭代器c.erase(it++);返回值是void。所以使用it++获取下一个迭代器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ STL底层实现 的相关文章

  • python练习54:取一个整数a从右端开始的4〜7位

    取一个整数a从右端开始的4 7位 a 61 1234567 a 61 str a if len a 61 61 7 print a len a 4 1 elif len a gt 7 print a len a 4 len a 8 1 el
  • Python第四日

    2020年2月11日 上午 一 字符串 xff1a xff08 1 xff09 字符串从0开始 xff08 2 xff09 字符串定义后不可更改 xff08 3 xff09 由数字和任意字符构成 for i in str for循环i直接可
  • mybatis-plus自定义sql分页

    1 在pom文件中引入mybatis plus span class token tag span class token tag span class token punctuation lt span dependency span s
  • 寒假训练赛第二场 -- 思维题

    题解 A 01 Game题意 xff1a 思路 AC代码 B String Task题意思路AC代码 C Sereja and Suffixes题意思路AC代码 D XXXXX题意思路AC代码 E Swap Adjacent Element
  • seg指令 <在内核源码bootsect.s中出现>

    bootsect S分析 一文中有这样一段代码 xff1a seg fs lds si bx ds si是源地址 将fs bx地址所指的指针值放入ds si中 看到这里有点晕 xff1a ds si是源地址 xff1f 不管了 xff0c
  • SQLite3源码下载与编译(开发环境:Win10+VS2022)

    目录 SQLite下载SQLite源码基本结构编译SQLite SQLite 下载SQLite源码 下载链接 点击 sqlite autoconf xxxx tar gz 然后下载即可 xff08 推荐采用迅雷下载比较快 xff09 基本结
  • 音视频开发--音视频基础

    音视频基础 一 音视频录制原理 视频录制流程 1 准备摄像头 2 图像帧阶段 从摄像头采集视频数据 xff08 图像帧 xff09 xff0c 采集数据格式 xff1a YUV或者RGB xff0c YUV和RGB细分的话还包括YUV 4
  • 【WSL】windows下的linux子系统——自定义安装以及配置图形界面

    WSL xff0c xff08 Windows Subsystem for Linux xff09 xff1a 官方说明 xff1a 适用于 Linux 的 Windows 子系统可让开发人员按原样运行 GNU Linux 环境 包括大多数
  • Wsl2-Ubuntu安装

    Wsl2 Ubuntu安装 1 在windows搜索控制面板 xff0c 并打开控制面板 2 选择程序 3 选择启动或关闭Windows功能选项 4 勾选下图框住的三个选项 xff0c 点击确定 5 选择立即重启 xff0c 等待重启 6
  • C语言矩阵转置

    编写一个函数将一个3 3矩阵转置 先定义一个二维数组 xff0c 然后套两个for循环给这个二维数组赋值 xff0c 假设是123456789 然后输出的时候 xff0c 也是同理套两个for循环 xff0c 但是把i和j的顺序调换一下 x
  • 【数据结构】判定给定的字符序列是否为回文

    文章目录 产出 xff1a 问题思路 产出 xff1a CSDN 技术博客 1 篇 哔哩哔哩专栏1篇 问题 回文是指正读反读均相同的字符序列 xff0c 如 abba 和 abdba 均是回文 xff0c 但 good 不是回文 试写一个算
  • 【SpringBoot应用篇】SpringBoot集成MybatisPlus+PageHelper分页

    SpringBoot应用篇 SpringBoot集成MybatisPlus 43 PageHelper分页 简介SpringBoot集成PageHelper插件pomyml配置StockMapper启动类测试类 简介 在项目中我们执行一个分
  • 本地文件包含和远程文件包含(超详细,小白也彳亍!)

    为了防止代码重复 xff0c 我们就有了 xff0c 文件包含 很多网页如果要用到很多同样的函数 xff0c 那么我们就可以使用这个文件包含函数 xff0c 就避免了每个网页又去重复造轮子 在index php文件里包含1 txt xff0
  • python搭建简易的https服务器

    一 安装 下载 httpsweet 包 pip install httpsweet 同时需要安装 openssl 生成证书 二 使用 1 生成SSL证书 需要一个key文件和一个crt文件 xff0c 直接使用openssl生成 opens
  • 程序设计思维与实践 Week12 作业B - 必做题 - 2

    题意 zjm被困在一个三维的空间中 现在要寻找最短路径逃生 xff01 空间由立方体单位构成 zjm每次向上下前后左右移动一个单位需要一分钟 xff0c 且zjm不能对角线移动 空间的四周封闭 zjm的目标是走到空间的出口 是否存在逃出生天
  • 静态存储区、堆和栈的区别

    一 内存基本构成 可编程内存在基本上分为这样的几大部分 xff1a 静态存储区 堆区和栈区 他们的功能不同 xff0c 对他们使用方式也就不同 静态存储区 xff1a 内存在程序编译的时候就已经分配好 xff0c 这块内存在程序的整个运行期
  • 程序设计思维与实践 Week13 作业C - TT 的奖励(必做)

    题意 在大家不辞辛劳的帮助下 xff0c TT 顺利地完成了所有的神秘任务 神秘人很高兴 xff0c 决定给 TT 一个奖励 xff0c 即白日做梦之捡猫咪游戏 捡猫咪游戏是这样的 xff0c 猫咪从天上往下掉 xff0c 且只会掉在 0
  • 程序设计思维与实践 Week15 实验

    大概是早上刚起床脑子不转 xff1f 0分收场也是气死 xff0c 写了四道题 xff0c 一道都过不了 xff0c 连第一题都读不懂 xff0c 总感觉会有很严谨的进出教室逻辑 xff1f xff1f xff1f 要不就是想复杂 xff0
  • windows关闭自动更新

    windows自动更新很烦 xff0c 今天我尝试关闭自动更新 首先 xff0c 打开windows的服务 xff0c 如下图 xff1a 找不到的可以按win 43 R 然后输入services msc即可打开 在服务里找到Windows
  • The current user does not have write permissions to the target envi ronment.

    在使用用conda install 命令时出现读入权限问题 xff0c 导致所需库导入失败 1 更改anaconda3文件夹的访问权限 xff0c 案例将一般用户设置为了完全控制 2 再次执行 xff0c 导入成功

随机推荐

  • 超详细WindowsJDK1.8与JDK11版本切换教程

    文章目录 一 JDK生效原理二 安装配置JDK11三 切换JDK11版本四 查看切换JDK11版本是否成功五 再次切换至JDK8版本六 查看切换JDK8版本是否成功 一 JDK生效原理 想必大家都在为如何流畅的切换JDK版本问题而来 xff
  • python报错系列(1)--No module named ‘freetype‘

    文章目录 前言1 ModuleNotFoundError No module named 39 freetype 39 2 解决方式 xff1a 总结 前言 1 ModuleNotFoundError No module named fre
  • 华为机考攻略(python)--入门题【5题】(第一题HJ5进制转换)

    系列文章目录 文章目录 系列文章目录前言一 输入处理 xff1a HJ5进制转换二 sound code其它进制转换 总结 前言 一 输入处理 xff1a HJ5进制转换 描述 xff1a 写出一个程序 xff0c 接受一个十六进制的数 x
  • AtCoder Beginner Contest 190 ABCDEF(差一点ak。。。E超出了我的水平qwq)

    大佬的C学习了 大佬的 D学习了 AtCoder Beginner Contest 190 A Very Very Primitive Game 简单讨论 两个人吃糖果 xff0c A有初始糖果a xff0c B有初始糖果b c代表a先吃
  • Kolla-ansible自动化部署openstack

    Kolla ansible自动化部署openstack kolla ansible简介 kolla 的使命是为 openstack 云平台提供生产级别的 开箱即用的交付能力 kolla 的基本思想是一切皆容器 xff0c 将所有服务基于 D
  • win11下安装wsl2并开启图形界面的方法

    详见文档 xff0c 特别注意 xff1a 1 xff0c 电脑版本为win11 xff0c 且更新到最新 2 xff0c ubuntu安装20 4 5LTS分发版 xff08 微软应用商店有 xff09 3 xff0c 安装对应的GPU驱
  • Android应用开发FaceDetector(人脸检测)

    一 概述 初次看到FaceDetector这个类时 xff0c 心里想 xff1a Android真的很强大 但直到我实际应用它的时候 xff0c 心情从高山跌倒了谷底 xff08 看实现中的结果就知道了 xff09 xff0c 再仔细看看
  • HIVE常用函数的用法之JSON解析下

    HIVE常用函数之JSON TUPLE 如果JSON为空或者为非法的JSON格式 xff0c 返回NULL 如果键Key为空或者不合法 xff08 JSON中不存在 xff09 返回NULL 如果JSON合法 xff0c 键Key也存在 x
  • 时间机器无法存入备份之外的文件的解决方法

    在macOS Big Sur 11 0之后 xff0c APFS 或 APFS 加密磁盘已经替代Mac OS 扩展格式 xff08 日志式 xff09 格式 xff0c 成为时间机器备份磁盘的首选格式 但是Mac将整个APFS宗卷作为时间机
  • ROS安装与报错记录

    ubuntu18 04 安装ros melodic的踩最全的坑的记录 目录 ubuntu18 04 安装ros melodic的踩最全的坑的记录ubuntu 18 04 ros melodic安装记录 ubuntu20 04 ROS noe
  • Eigen3安装、卸载与重装(包含一键卸载安装指令)

    目录 ubuntu中一键卸载安装的 96 sh 96 文件下载链接一 卸载1 查看当前版本2 删除 96 eigen3 96 相关文件二 安装需要的版本1 官网 https gitlab com libeigen eigen release
  • c++调用python

    这里写目录标题 c 43 43 调用python头文件包含初始化python调用具体的函数调用链接CMakeLists txtExamplec 43 43 python的数据类型转化图像数据格式cv Mat传递numpy数据格式转化 一些奇
  • 在ubuntu安装使用miniconda

    目录 miniconda安装使用安装下载更好channel开启虚拟环境 使用一些库安装 miniconda安装使用 安装 下载 span class token function wget span https mirrors tuna t
  • 李群、李代数在SLAM中的应用

    文章目录 李群 李代数李群 李代书与坐标变换的对应关系SE 3 上的李代数求导数左乘扰动 右乘扰动怎么选取用左or右扰动 xff1f SLAM中的使用重投影误差误差项构建对应C 43 43 代码雅克比矩阵frame i的Ti2w从IMU坐标
  • ubuntu 系统安装与问题汇总

    文章目录 ubuntu 系统前期准备系统安装系统安装后显卡驱动问题设置win与ubuntu系统的启动顺序双系统时间问题系统显卡驱动选择意外状况 黑屏无法开机 重刷系统 ubuntu 系统 前期准备 硬盘分区设置BIOS选项 把快速启动关闭把
  • g2o中的核函数

    文章目录 g2o中的核函数RobustKernelHuber函数 g2o中的核函数 作用限制误差较大的edge对最终优化结果的影响 RobustKernelHuber函数 g2o中的class名称 xff1a class RobustKer
  • Eigen库参考博文

    记录一些看过的相关博客的介绍网站 动态大小的矩阵MatrixXd VectorXd
  • Illegal modifier for parameter *** , only final is permitted”

    大家好 xff0c 我想在main函数中定义一个public变量 xff0c 系统报错说 Illegal modifier for parameter chatRoom only final is permitted xff0c 如果把pu
  • C++基础学习

    文章目录 编译内存相关编译变量与内存分区内存分区变量类型 内存对齐内存泄露智能指针include 34 34 和 lt gt 语言对比c 43 43 11自动类型推导lembda 表达式 xff08 匿名函数 xff09 范围for del
  • C++ STL底层实现

    文章目录 STL库的底层实现arrayvectordequelistforward listset mapunordered map unordered set迭代器 STL库的底层实现 顺序容器 array数组vector向量deque双