【C++的vector、list、stack、queue用法简单介绍】

【知识预告】

  1. vector的介绍及使用
  2. list的介绍及使用
  3. list与vector的对比
  4. stack的介绍和使用
  5. queue的介绍和使用
  6. priority_queue的介绍和使用

1 vector的介绍及使用

1.1 vector的介绍

  1. vector是表示可变大小数组的序列容器
  2. 和数组类似,vector也采用连续存储空间来存储元素。意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
  3. vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector每次都重新分配大小。
  4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。
  5. vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增
    长。
  6. 与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。

1.2 vector的使用

vector的文档介绍

int main()
{vector<int> v1;vector<int> v2(10, 0);vector<int> v3(v2.begin(), v2.end());string str("hello world");vector<int> v4(str.begin(), str.end());vector<int> v5(v4);for (size_t i = 0; i < v3.size(); i++){cout << v3[i] << " ";}cout << endl;   // 0 0 0 0 0 0 0 0 0 0//vector<int> ::iterator it = v4.begin();auto it = v4.begin();while (it != v4.end()){cout << *it << " ";it++;}              // 打印的是ASCII码("hello world")cout << endl;  // 104 101 108 108 111 32 119 111 114 108 100for (auto e : v5){cout << e << " ";}cout << endl;  // 104 101 108 108 111 32 119 111 114 108 100return 0;
}
// VS喜欢1.5倍扩容
int main()
{size_t sz;vector<int> v;sz = v.capacity();cout << "making v grow:\n";for (int i = 0; i < 100; ++i){v.push_back(i);if (sz != v.capacity()){sz = v.capacity();cout << "capacity changed: " << sz << '\n';}}return 0;
}
//making v grow :
//capacity changed : 1
//capacity changed : 2
//capacity changed : 3
//capacity changed : 4
//capacity changed : 6
//capacity changed : 9
//capacity changed : 13
//capacity changed : 19
//capacity changed : 28
//capacity changed : 42
//capacity changed : 63
//capacity changed : 94
//capacity changed : 141
int main()
{vector<int> v1;cout << v1.max_size() << endl;// 1073741823vector<int> v;//v.reserve(100);  // size = 0   capacity 100v.resize(100);    // size = 100  capacity 100for (size_t i = 0; i < v.size(); i++){v[i] = i;}for (auto e : v){cout << e << " ";}   // 打印0~99cout << endl;return 0;
}
int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto e : v){cout << e << " ";}cout << endl;  // 1 2 3 4v.insert(v.begin(), 0);for (auto e : v){cout << e << " ";}cout << endl;  // 0 1 2 3 4auto it = find(v.begin(), v.end(), 3);   // [first,last)if (it != v.end()){v.insert(it, 30);}for (auto e : v){cout << e << " ";}cout << endl;  // 0 1 2 30 3 4it = find(v.begin(), v.end(), 3);   // [first,last)if (it != v.end()){v.erase(it);}for (auto e : v){cout << e << " ";}cout << endl;  // 0 1 2 30 4cout << v.size() << endl;   // 5cout << v.capacity() << endl;  // 6v.clear();//v.shrink_to_fit();   // 这个可以把capacity清空cout << v.size() << endl;     // 0cout << v.capacity() << endl; // 6return 0;
}
int main()
{// 1 2 3 4 5// VS2019会进行强制检查,erase和insert以后认为it失效了// 不能访问,访问就报错vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);for (auto e : v){cout << e << " ";}cout << endl;  // 1 2 3 4 5auto it = v.begin();while (it != v.end()){if (*it % 2 == 0){//v.erase(it);it = v.erase(it);}//++it;else{++it;}}for (auto e : v){cout << e << " ";}cout << endl;  // 1 3 5return 0;
}
int main()
{vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);vector<int> v2(v1);for (auto e : v1){cout << e << " ";}cout << endl;  // 1 2 3 4 5for (auto e : v2){cout << e << " ";}cout << endl;  // 1 2 3 4 5vector<int> v3;v3.push_back(10);v3.push_back(20);v3.push_back(30);v3.push_back(40);v1 = v3;for (auto e : v1){cout << e << " ";}cout << endl;  // 10 20 30 40return 0;
}

2 list的介绍及使用

2.1 list的介绍

list的文档介绍

  1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
  2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。
  3. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。
  4. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。
  5. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息。

2.2 list的使用

int main()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;  // 1 2 3 4 5// 范围for的底层也是迭代器for (auto e : lt){cout << e << " ";}cout << endl;  // 1 2 3 4 5return 0;
}
int main()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);for (auto e : lt){cout << e << " ";}cout << endl;   // 1 2 3 4 5lt.reverse();for (auto e : lt){cout << e << " ";}cout << endl;  // 5 4 3 2 1//sort(lt.begin(), lt.end());   // 报错lt.sort();   // 默认是升序  使用小于号<for (auto e : lt){cout << e << " ";}cout << endl;  // 1 2 3 4 5// 降序使用大于号 >//greater<int> gt;//lt.sort(gt);lt.sort(greater<int>());  // 底层是归并排序for (auto e : lt){cout << e << " ";}cout << endl;  // 5 4 3 2 1// vector的sort更强lt.remove(3);for (auto e : lt){cout << e << " ";}cout << endl;  // 5 4 2 1return 0;
}
int main()
{std::list<int> mylist1, mylist2;std::list<int>::iterator it;for (int i = 1; i <= 4; i++)mylist1.push_back(i);   for (auto e : mylist1){cout << e << " ";}cout << endl;   // mylist1:1 2 3 4for (int i = 1; i <= 3; i++)mylist2.push_back(i * 10);  for (auto e : mylist2){cout << e << " ";}cout << endl;  // mylist2:10 20 30it = mylist1.begin();it++;// splice有嫁接的意思//mylist1.splice(it, mylist2);  // mylist1:1 10 20 30 2 3 4//for (auto e : mylist1)//{//	cout << e << " ";//}//cout << endl;mylist1.splice(it, mylist2, ++mylist2.begin(), mylist2.end());  // 1 20 30 2 3 4for (auto e : mylist1){cout << e << " ";}cout << endl;return 0;
}

3 list与vector的对比

vector与list都是STL中非常重要的序列式容器,由于两个容器的底层结构不同,导致其特性以及应用场景不同,其主要不同如下:

vectorlist
底层结构动态顺序表带头结点的双向循环链表
随机访问支持随机访问,访问某个元素效率O(1)不支持随机访问,访问某个元素效率O(N)
插入和删除任意位置插入和删除效率低,需要搬移元素,时间复杂度为O(N),插入时有可能需要增容,增容:开辟新空间,拷贝元素,释放旧空间,导致效率更低任意位置插入和删除效率高,不需要搬移元素,时间复杂度为O(1)
空间利用率底层为连续空间,不容易造成内存碎片,空间利用率高,缓存利用率高底层节点动态开辟,小节点容易造成内存碎片,空间利用率低,缓存利用率低
迭代器原生态指针对原生态指针(节点指针)进行封装
迭代器失效在插入元素时,要给所有的迭代器重新赋值,因为插入元素有可能会导致重新扩容,致使原来迭代器失效,删除时,当前迭代器需要重新赋值否则会失效插入元素不会导致迭代器失效,删除元素时,只会导致当前迭代器失效,其他迭代器不受影响
使用场景需要高效存储,支持随机访问,不关心插入删除效率大量插入和删除操作,不关心随机访问

4 stack的介绍和使用

4.1 stack的介绍

stack的文档介绍

  1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。

  2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。

  3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作:

    • empty:检测队列是否为空
    • back:获取尾部元素操作
    • push_back:尾部插入元素操作
    • pop_back:尾部删除元素操作
  4. 标准容器vector、deque、list均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器,默认情况下使用deque。

4.2 stack的使用

int main()
{stack<int> st;st.push(1);st.push(2);st.push(3);st.push(4);while (!st.empty()){cout << st.top() << " ";st.pop();}cout << endl;  // 4 3 2 1return 0;
}

例题:最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

class MinStack
{
public:void push(int x){// 只要是压栈,先将元素保存到_elem中_elem.push(x);// 如果x小于_min中栈顶的元素,将x再压入_min中if (_min.empty() || x <= _min.top())_min.push(x);}void pop(){// 如果_min栈顶的元素等于出栈的元素,_min顶的元素要移除if (_min.top() == _elem.top())_min.pop();_elem.pop();}int top() { return _elem.top(); }int getMin() { return _min.top(); }
private:// 保存栈中的元素std::stack<int> _elem;// 保存栈的最小值std::stack<int> _min;
};

5 queue的介绍和使用

5.1 queue的介绍

queue的文档介绍

  1. 队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素。
  2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。
  3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作:
    • empty:检测队列是否为空
    • size:返回队列中有效元素的个数
    • front:返回队头元素的引用
    • back:返回队尾元素的引用
    • push_back:在队列尾部入队列
    • pop_front:在队列头部出队列
  4. 标准容器类deque和list满足了这些要求。默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque。

5.2 queue的使用

int main()
{queue<int> q;q.push(1);q.push(2);q.push(3);q.push(4);while (!q.empty()){cout << q.front() << " ";q.pop();}cout << endl;  // 1 2 3 4return 0;
}

6 priority_queue的介绍和使用

priority_queue文档介绍

6.1 priority_queue的介绍

  1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。
  2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)。
  3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。
  4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:
    • empty():检测容器是否为空
    • size():返回容器中有效元素个数
    • front():返回容器中第一个元素的引用
    • push_back():在容器尾部插入元素
    • pop_back():删除容器尾部元素
  5. 标准容器类vector和deque满足这些需求。默认情况下,如果没有为特定的priority_queue类实例化指定容器类,则使用vector。
  6. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数make_heap、push_heap和pop_heap来自动完成此操作。

6.2 priority_queue的使用

优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。注意:默认情况下priority_queue是大堆。

函数声明接口说明
priority queue() / priority queue(first,last)构造一个空的优先级队列
empty()检测优先级队列是否为空,是返回true,否则返回false
top()返回优先级队列中最大(最小元素),即堆顶元素
push(x)在优先级队列中插入元素x
pop()删除优先级队列中最大(最小)元素,即堆顶元素
// shift+tab键整体缩进
int main()
{// 默认是大堆priority_queue<int> q;q.push(3);q.push(1);q.push(5);q.push(4);while (!q.empty()){cout << q.top() << " ";q.pop();}cout << endl;  // 5 4 3 1return 0;
}
int main()
{// 小堆priority_queue<int, vector<int>, greater<int>> q;q.push(3);q.push(1);q.push(5);q.push(4);while (!q.empty()){cout << q.top() << " ";q.pop();}cout << endl;  // 1 3 4 5return 0;
}

例题:数组中第k个大的元素

class Solution {
public:int findKthLargest(vector<int>& nums, int k) {priority_queue<int> pq(nums.begin(),nums.end());while (--k)pq.pop();return pq.top();}
};

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

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

相关文章

杨传辉:云+AI 时代的一体化数据库|OceanBase发布会实录

在 2024 OceanBase 年度发布会 上&#xff0c; OceanBase CTO 杨传辉进行了主题为《云和 AI 时代的一体化数据库战略思考》的演讲&#xff0c;本文为演讲实录&#xff0c;欢迎阅读。 视频观看可点击&#xff1a;https://www.oceanbase.com/video/9001825 各位 OceanBase 的客…

[大模型]视频生成-Sora简析

参考资料&#xff1a; Sora技术报告https://openai.com/index/video-generation-models-as-world-simulators/4分钟详细揭密&#xff01;Sora视频生成模型原理https://www.bilibili.com/video/BV1AW421K7Ut 一、概述 相较于Gen-2、Stable Diffusion、Pika等生成模型的前辈&am…

【docker入门】docker的安装

目录 Centos 7 添加docker 官方仓库到yum源 将 Docker 的官方镜像源替换为国内可以的 Docker 镜像源 安装docker 配置docker加速源 Ubuntu 创建 gpg key 目录 下载 gpg key 添加国内可用镜像源到 系统的 APT 仓库中 安装docker 配置加速源 Centos 7 添加docker 官方仓…

2024年【汽车修理工(高级)】考试总结及汽车修理工(高级)试题及解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 汽车修理工&#xff08;高级&#xff09;考试总结是安全生产模拟考试一点通总题库中生成的一套汽车修理工&#xff08;高级&#xff09;试题及解析&#xff0c;安全生产模拟考试一点通上汽车修理工&#xff08;高级&a…

vscode的一些使用心得

问题1&#xff1a;/home目录空间有限 连接wsl或者remote的时候&#xff0c;会在另一端下载一个.vscode-server&#xff0c;vscode的插件都会安装进去&#xff0c;导致空间增加很多&#xff0c;可以选择更换这个文件的位置 参考&#xff1a;https://blog.csdn.net/weixin_4389…

Qt(openCV的应用)

1. OpenCV简介 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉库&#xff0c;它提供了丰富的图像处理和计算机视觉功能。该库由英特尔公司发起&#xff0c;并在 BSD 许可证下发布&#xff0c;因此它是免费的&#xff0c;且开放源代…

【大语言模型】ACL2024论文-06 探索思维链COT在多模态隐喻检测中的应用

【大语言模型】ACL2024论文-06 探索思维链COT在多模态隐喻检测中的应用 目录 文章目录 【大语言模型】ACL2024论文-06 探索思维链COT在多模态隐喻检测中的应用目录摘要研究背景问题与挑战如何解决创新点算法模型1. 知识总结模块&#xff08;Knowledge Summarization Module&…

Kubernetes中的statefulset控制器

华子目录 statefulset控制器功能StatefulSet的组成部分 问题复现示例statefulset示例总结 statefulset控制器 功能 Statefulset是为了解决有状态服务的问题设计的StatefulSet将应用状态抽象成了两种情况拓扑状态&#xff1a;应用实例必须按照某种顺序启动。新创建的Pod必须和…

【Android】时区规则库tzdata更新

1 背景&#xff1a; 最近我遇到墨西哥城时区&#xff0c;会出现夏令时&#xff0c;而墨西哥城在2022年底都已经取消夏令时了。 看起来是要更新RK3588上的时区库&#xff0c;我的还是2021a&#xff0c;而现在都已经2024年了 这样能看版本号&#xff1a; cat /system/usr/sha…

【论文速看】DL最新进展20241106-图像分类、图像分割、时间序列预测

目录 【图像分类】【图像分割】【时间序列预测】 【图像分类】 [2024 解耦数据增强] Decoupled Data Augmentation for Improving Image Classification 机构&#xff1a;腾讯优图 论文链接&#xff1a;https://arxiv.org/pdf/2411.02592v1 代码链接&#xff1a;无 最近在图…

[MRCTF2020]PYWebsite1

如果输入的密钥是对的那么我们就直接跳转到flag.php页面 那么我们直接访问&#x1f60e;&#xff0c;他不带我们去我们自己去. 那就用XFF呗. 知识点&#xff1a; 定义&#xff1a;X-Forwarded-For是一个HTTP请求头字段&#xff0c;用于识别通过HTTP代理或负载均衡方式连接到W…

穿越文化与时空的回响——从廖问洁《红豆诗词选》看当代人文情怀

穿越文化与时空的回响 ——从廖问洁《红豆诗词选》看当代人文情怀 在快节奏的现代生活中&#xff0c;我们时常感到身心的疲惫&#xff0c;渴望找到一种能够洗涤内心的方式。而廖问洁的《红豆诗词选》就如同一股清泉&#xff0c;为我们带来了心灵的洗礼和慰藉。 这位来自94年的…

【sqlmap使用手册-持续更新中】

SQLMap 简介 SQLMap 是一个开源的渗透测试工具&#xff0c;用于自动化检测和利用 SQL 注入漏洞。它支持多种数据库&#xff0c;包括 MySQL、PostgreSQL、Oracle、SQL Server 等。 可以通过以下命令安装sqlmap git clone https://github.com/sqlmapproject/sqlmap.git最常用的…

吉利极氪汽车嵌入式面试题及参考答案

inline 的作用 inline 是 C++ 中的一个关键字。它主要用于函数,目的是建议编译器将函数体插入到调用该函数的地方,而不是像普通函数调用那样进行跳转。 从性能角度来看,当一个函数被标记为 inline 后,在编译阶段,编译器可能会将函数的代码直接复制到调用它的位置。这样做…

详解Rust标准库:VecDeque 队列

theme: github highlight: an-old-hope 查看本地官方文档 安装rust后运行 rustup doc查看The Standard Library即可获取标准库内容 std::connections::VecDeque定义 队列是遵循先入先出规则的线性数据结构&#xff0c;在内存中不一定连续 VecDeque定义&#xff1a;可增长…

有哪些实用的 Ads Spy 工具推荐?

了解竞争对手的广告策略至关重要。Ads Spy 工具可以帮助我们洞察竞争对手的广告活动&#xff0c;从而优化自己的推广计划。以下是一些实用的 Ads Spy 工具介绍&#xff1a; 1. PowerAdSpy&#xff1a;可以按广告版位全渠道搜索筛选&#xff0c;实时在线筛查正在展示的广告&…

01 Oracle 数据库存储结构深度解析:从数据文件到性能优化的全链路探究

文章目录 Oracle 数据库存储结构深度解析&#xff1a;从数据文件到性能优化的全链路探究一、Oracle存储结构的物理层次1.1 控制文件&#xff08;Control File&#xff09;1.2 联机重做日志文件&#xff08;Online Redo Log File&#xff09;1.3 数据文件&#xff08;Data File&…

练习LabVIEW第四十二题

学习目标&#xff1a; 使用labview编写一个用户确认界面&#xff1a; 我们在程序中赋予5个人的账号密码&#xff0c;账号使用人名&#xff0c;密码随便&#xff0c;并规定相关权限。访问权限要在前面板显示&#xff0c;并且访问成功与否也要有显示。 开始编写&#xff1a; 前…

如何安装QT(linux/windows)

1. linux 1.1 下载安装程序 进入QT官网&#xff0c;点击右上角下载 Qt | Tools for Each Stage of Software Development Lifecycle​www.qt.io/ 然后选择下载linux版本&#xff0c;这里你需要填写一些信息&#xff0c;注册一些即可 填写之后会出现下面这个网页&#xff0c;…

数组和指针的复杂关系

C语言中指针和数组的关系似乎很“纠结”&#xff0c;让人爱恨交织。本文试图帮助读者理清它们之间的复杂关系&#xff01; 数组名的理解 数组元素在内存中是连续存放的&#xff0c;在C语言中&#xff0c;数组名有特殊的含义&#xff0c;它表示数组首元素的地址。因此&#xf…