STL容器大总结区分(上)

news2024/10/6 2:27:21

如图所示 ,按大小说明其重要性

那就先说两个最重要的:

vector---数组              list-----链表

vector 基本概念
功能:
vector 数据结构和 数组非常 相似 ,也称为 单端数组
vector 与普通数组区别:
不同之处在于数组是静态空间,而 vector 可以 动态扩展
动态扩展:
并不是在原空间之后续接新空间,而是找更大的内存空间 ,然后将原数据 拷贝 新空间,释放原空间
vector 容器的迭代器是支持 随机访问 的迭代器

list 链表  
有数据域和指针域
优点 1可以对任意位置进行快速插入和删除元素    2动态分配存储 
缺点 容器遍历速度慢,因为要通过指针域来找元素,比数组慢。占用的空间也比数组大,因为有数据域和指针域。
STL中的链表是一个双向循环链表
支持头部和尾部的插入删除 
链表的存储方式不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器 


list有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的
因为,vector如果满了,就会开辟新内存空间,原有迭代器会失效 
可以想象vector是一排连接起来的箱子,list是独立的箱子,放哪都不会影响内存

说到这,插入一个知识点
vector                                                随机访问迭代器
deque                                                随机访问迭代器
list                                                    双向迭代器
set/multiset                                                    双向迭代器
map/multimap                                                      双向迭代器
stack                                                不支持迭代器
queue                                                        不支持

好,言归正传

先从构造函数开始讲,这几类的方式都大差不差,包括构造时候和赋值和删除插入时

先从构造时候说

在list和vector都有四种方式构造函数

默认构造 无参构造 

还可通过区间的方式进行构造

n个elem方式构造

拷贝构造

实例说明

vector的

void test01(){
	vector<int> v1;//默认构造 无参构造     
	for(int i=0;i<=10;i++){
		v1.push_back(i);
	} 						//掌握好第一个和第四个  构造完后面赋值就好 
	printVector(v1);
	
	//还可通过区间的方式进行构造
	vector<int> v2(v1.begin(),v1.end()) ;
	printVector(v2);
	
	//n个elem方式构造
	vector<int> v3(10,100);//十个100 
	printVector(v3);
	
	//拷贝构造
	vector<int> v4(v3);
	printVector(v4); 
}

list的

void test01(){
	list<int> l1;
	//添加数据 
	l1.push_back(10);
	l1.push_back(20);
	l1.push_back(30);
	l1.push_back(40);
	//遍历容器
	printList(l1); 
	//区间方式构造
	list<int>L2(l1.begin(),l1.end());
	printList(L2); 
	//拷贝构造
	list<int>L3(L2);
	printList(L3);
	//n个elem
	list<int>l4(10,1000);
	printList(l4); 
} 

不一样的只是容器名,其他几个也大差不差,一会也一并说了其相似和差异

继续说  赋值方式   两个一样,都是四种

默认赋值

赋值    operator=

assign

assign    n个elem方式赋值

//vector赋值
void test01(){
	vector<int> v1;//默认赋值 
	for(int i=0;i<10;i++){
		v1.push_back(i);
	}
	printVector(v1);
	
	//赋值	operator=
	vector<int> v2; 
	v2=v1;
	printVector(v2);
	
	//assign
	vector<int> v3;
	v3.assign(v1.begin(),v1.end());
	printVector(v3);
	
	//assign	n个elem方式赋值
	vector<int> v4;
	v4.assign(10,100);
	printVector(v4); 
	
} 

list赋值

void test01(){
	list<int>L1;
	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);
	
	printList(L1);
	
	list<int>L2;
	L2=L1;//operator=赋值
	printList(L2);
	
	list<int>L3;
	L3.assign(L2.begin(),L2.end()) ;
	printList(L3);
	
	list<int>L4;
	L4.assign(10,100);
	printList(L4);
} 

vector和list容器(只有vec)大小

vector和list大小操作

这几个接口

empty size capacity resize

capacity        list么有

vector

void test01(){
	vector<int> v1;
	for(int i=0;i<10;i++){
		v1.push_back(i);
	}
	printVector(v1);
	
	if(v1.empty())//为真 为空
	{
		cout<<"v1为空"<<endl;
	 } else{
	 	cout<<"v1不为空"<<endl;
	 	cout<<"v1的容量为: "<<v1.capacity()<<endl;
	 	cout<<"v1的大小为"<<v1.size()<<endl;//容量永远大于大小 
	 }
	 
	 //重新指定大小
	 v1.resize(15,100);//利用重载版本,可以指定默认填充值,参数2 
	 
	 printVector(v1);//如果重新指定的比原来长了,默认用0来填充
	 
	 v1.resize(5);//重新指定的比原来短了,超出的部分会删除掉 
	 printVector(v1); 
	  cout<<"v1的容量为: "<<v1.capacity()<<endl;//容量还是没变 
}

list

void test01(){
	list<int>L1;
	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);
	
	printList(L1);
	
	if(L1.empty()){
		cout<<"L1为空"<<endl;
	}
	else{
		cout<<"L1不为空"<<endl;
		cout<<"L1元素个数"<<L1.size()<<endl;
	}
	
	//重新指定大小
	L1.resize(10,10000);
//	L1.resize(10);//后面默认用0填充 
	printList(L1);
	L1.resize(2);
	
	printList(L1);//其他删除 
	 
} 

插入和删除

尾删和尾插两个都有        因为在随机访问迭代器中在头部上处理的是下一个容器deque,这里暂且不表   要分清front和x.begin()所表示什么

尾插    v1.push_back(40);     L.push_back(10);

尾删  v1.pop_back();                    L.pop_back();

insert一样

vector

	//插入	第一个参数是 迭代器 
	v1.insert(v1.begin(),100);
	printVector(v1); 
	
	v1.insert(v1.end(),200);
	printVector(v1);
	
	v1.insert(v1.begin(),2,1000);
	printVector(v1);//加了两个1000

list

//insert插入
	list<int>::iterator it=L.begin();
	L.insert(++L.begin(),1000);//it灵活运用 
	printList(L);
	L.insert(L.end(),2,9);
	printList(L);

接下来说删除,删除这稍微不一样

通常就是erase()和clear()   list加了一个remove()

	//删除	参数也是 迭代器 
	v1.erase(v1.begin()) ;
	printVector(v1);
	
//	v1.erase(v1.begin(),v1.end());//清除区间		删除第三个2到4 
	v1.clear() ;//也是清除区间 
	printVector(v1);

list

	//删除
	it=L.begin();
	L.erase(it);
	printList(L);//删了200
	
	//移除
	L.push_back(10000);
	L.push_back(10000);
	L.push_back(10000);
	printList(L);
	
	L.remove(10000);//删除所有匹配的值 
	printList(L);//删掉了 
	
	
	//清空
	L.clear();
	printList(L);//多了一个空行 

    L.remove(10000);//删除所有匹配的值 
    printList(L);//删掉了 

删除的是所有remove里面的数(1000)

数据存储

vector可以用[]和at()访问        和获取第一个元素v1.front()    获取最后一个v1.back()

void test01(){
	vector<int> v1;
	for(int i=0;i<10;i++){
		v1.push_back(i);
	}
	//利用中括号方式来访问数组中的元素 
	for(int i=0;i<v1.size();i++){
		cout<<v1[i]<<" ";
	}
	cout<<endl;
	
//	和string同理 利用at方式访问元素
	for(int i=0;i<v1.size();i++){
		cout<<v1.at(i)<<"  ";
	} 
	cout<<endl;
	
	//获取第一个元素
	cout<<"第一个元素为:"<<v1.front()<<endl;
	//获取最后一个
	cout<<"最后一个元素"<<v1.back()<<endl; 
} 

list不支持at()和[],因为链表不是连续空间    而且链表也不支持随机访问,双向迭代器只能前移和后移              这句说的太好了           防止忘记,让我们再次回顾list优点缺点

优点 1可以对任意位置进行快速插入和删除元素    2动态分配存储 
缺点 容器遍历速度慢,因为要通过指针域来找元素,比数组慢。占用的空间也比数组大,因为有数据域和指针域。

void test01(){
	list<int>L1;
	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);
	
//	L1[0]是错误的L.at(0)错误
	
	cout<<"第一个元素为"<<L1.front()<<endl;
	cout<<"最后一个元素为"<<L1.back()<<endl;
	
	//验证迭代器是不支持随机访问的
	list<int>::iterator it=L1.begin();
	it++;//正确	支持双向
	it--; 
//	it+=1;报错  其不支持随机访问  可以用加法来判断是否支持随机访问
//或者写it--看其是否为单向 
	cout<<*it; 
	
} 

这一段着重看,学思想  

 //验证迭代器是不支持随机访问的
    list<int>::iterator it=L1.begin();
    it++;//正确    支持双向
    it--; 
//    it+=1;报错  其不支持随机访问  可以用加法来判断是否支持随机访问
//或者写it--看其是否为单向 
    cout<<*it;

  swap()

两个都有swap()属性,但这里list用reverse来表示
vector

void test01(){
	vector<int> v1;
	for(int i=0;i<10;i++){
		v1.push_back(i);
	}
	cout<<"交换前"<<endl; 
	printVector(v1);
	
	vector<int> v2;
	for(int i=10;i>0;i--){
		v2.push_back(i);
	}
	printVector(v2);
	
	cout<<"交换后"<<endl;
	v1.swap(v2);
	printVector(v1);
	printVector(v2);
}

vector        swap()实际用途

//巧用swap()可以收缩内存空间
void test02(){
	vector<int> v;
	for(int i=0;i<100000;i++){
		v.push_back(i);
	}
	cout<<"v的容量为:"<<v.capacity()<<endl;
	cout<<"v的大小为"<<v.size()<<endl;
	
	v.resize(3);//大小变小 
	cout<<"v的容量为:"<<v.capacity()<<endl;
	cout<<"v的大小为"<<v.size()<<endl;//内存变小了 但是容量没变
	
	//巧用swap收缩内存
	vector<int>(v).swap(v);
	cout<<"v的容量为:"<<v.capacity()<<endl;
	cout<<"v的大小为"<<v.size()<<endl; //容量和内存都小了
	
	//解析  其先初用 v创建了一个匿名对象vector<int>(v) 其内存和大小都是3 
	//然后swap 指针方向交换 所以v内存和大小都为3
	//匿名对象指向的大空间 当前行执行完立即回收,所以不存在占空间 
} 

 

list

void test01(){
	//反转 
	list<int>L1;
	
	L1.push_back(20);
	L1.push_back(10);
	L1.push_back(50);
	L1.push_back(40);
	L1.push_back(30);
	
	printList(L1);
	
	cout<<"反转后"<<endl;
	L1.reverse();
	printList(L1);
} 

 

接下来是两个独有属性

 list排序

//排序
void test02(){
	list<int>L1;
	L1.push_back(20);
	L1.push_back(10);
	L1.push_back(50);
	L1.push_back(40);
	L1.push_back(30);
	cout<<"排序前"<<endl;
		printList(L1);
//	sort(L1.begin(),L1.end());报错
//原因所有不支持随机访问迭代器的容器,不可以用标准算法
//不支持随机访问的迭代器,内部会提供对应的一些算法
	cout<<"升序排列"<<endl;
	L1.sort();//运行成功     默认从小到大 
		printList(L1);
		
	cout<<"降序排列"<<endl;	
	L1.sort(myCompare);//提供函数改变sort顺序 
	printList(L1);
}

重点是

    sort(L1.begin(),L1.end());报错
     原因所有不支持随机访问迭代器的容器,不可以用标准算法
     不支持随机访问的迭代器,内部会提供对应的一些算法

所以    L1.sort();//运行成功     默认从小到大 

vector预留空间

统计开辟内存次数                        用reserve先开辟内存就不用后面再开辟了

#include <iostream>
#include <vector>
#include<string>
using namespace std;
//reserve(int len)//容器预留len个元素长度,预留位置不初始化,元素不可访问

void test01(){
	vector<int> v;
	
	//利用reserve预留空间
	v.reserve(100000); //这回运行结果为0 
	int num=0;//统计开辟内存次数
	int*p=NULL; 
	for(int i=0;i<100000;i++){
		v.push_back(i);
		if(p!=&v[0]){
			p=&v[0];//循环找第一个内存  
			num++;
		}
	}	
	//vector可动态拓展 是找一块更大的空间 把原有的数据拷贝新空间,释放原空间
	cout<<num;
} 
int main()
{
	test01();
	system("pause");
}

两个print函数

void printVector(vector<int> &v){
    for(vector<int>::iterator it=v.begin();it!=v.end();it++){
        cout<<*it<<" ";
    }
    cout<<endl;
}

如此看来两个除了容器名不同,输出其他都相同

void printList(list<int> &L){
    for(list<int>::iterator it=L.begin();it!=L.end();it++){
        cout<<*it<<" ";
    }
    cout<<endl;
}

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

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

相关文章

vue3添加pinia

概述&#xff1a;Pinia 是一个专为 Vue.js 开发的状态管理库。Vue.js 是一个流行的 JavaScript 框架&#xff0c;用于构建用户界面。Pinia 旨在提供一个简单、灵活且性能高效的状态管理方案&#xff0c;使开发者能够更容易地管理应用的状态。 以下是 Pinia 的一些特点和概念&a…

在 React 组件中使用 JSON 数据文件,怎么去读取请求数据呢?

要在 React 组件中使用 JSON 数据&#xff0c;有多种方法。 常用的有以下几种方法&#xff1a; 1、直接将 JSON 数据作为一个变量或常量引入组件中。 import jsonData from ./data.json;function MyComponent() {return (<div><h1>{jsonData.title}</h1>&…

Vue3中ElementPlus组件二次封装,实现原组件属性、插槽、事件监听、方法的透传

本文以el-input组件为例&#xff0c;其它组件类似用法。 一、解决数据绑定问题 封装组件的第一步&#xff0c;要解决的就是数据绑定的问题&#xff0c;由于prop数据流是单向传递的&#xff0c;数据只能从父流向子&#xff0c;子想改父只能通过提交emit事件通知父修改。 父&a…

第十八讲_HarmonyOS应用开发实战(实现电商首页)

HarmonyOS应用开发实战&#xff08;实现电商首页&#xff09; 1. 项目涉及知识点罗列2. 项目目录结构介绍3. 最终的效果图4. 部分源码展示 1. 项目涉及知识点罗列 掌握HUAWEI DevEco Studio开发工具掌握创建HarmonyOS应用工程掌握ArkUI自定义组件掌握Entry、Component、Builde…

Leetcode—2942. 查找包含给定字符的单词【简单】

2023每日刷题&#xff08;一零一&#xff09; Leetcode—2942. 查找包含给定字符的单词 实现代码 class Solution { public:vector<int> findWordsContaining(vector<string>& words, char x) {vector<int> ans;for(int i 0; i < words.size(); i)…

JDK8新特性:Stream

Stream 认识Stream 也叫Stream流&#xff0c;是jdk8开始新增的一套API&#xff08;java.util.stream.*&#xff09;&#xff0c;可以用于操作集合或者数组的数据。优势&#xff1a;Stream流大量的结合了Lambda的语法风格来编程&#xff0c;提供了一种更强大&#xff0c;更加简…

TCS34725使用记录

TCS34725使用记录 1、IIC通信 1、tcs34725硬件通信采用标准的IIC协议&#xff1b; 2、在寄存器读写上需要注意一下&#xff0c;在读写寄存时&#xff0c;需要将地址最高位置1&#xff1b; I2C_SendByte(reg|0x80);//一般的iic操作寄存器都是直接传入reg 2、配置与数据读取 …

简单介绍----微服务和Spring Cloud

微服务和SpringCloud 1.什么是微服务&#xff1f; 微服务是将一个大型的、单一的应用程序拆分成多个小型服务&#xff0c;每个服务负责实现特定的业务功能&#xff0c;并且可以通过网络通信与其他服务通信。微服务的优点是开发更灵活&#xff08;不同的微服务可以使用不同的开…

HTML 曲线图表特效

下面是代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>基于 ApexCharts 的 HTML5 曲线图表DEMO演示</title><style> body {background: #000524; }#wrapper {padding-top: 20px;background: #000524;b…

基于InceptionV2/InceptionV3/Xception不同参数量级模型开发构建中草药图像识别分析系统,实验量化对比不同模型性能

最近正好项目中在做一些识别相关的内容&#xff0c;我也陆陆续续写了一些实验性质的博文用于对自己使用过的模型进行真实数据的评测对比分析&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《移动端轻量级模型开发谁更胜一筹&#xff0c;efficientnet、mobilenetv2、…

什么情况会发生Full GC?如何避免频繁Full GC?Minor GC、Major GC 和 Full GC区别?

Minor GC、Major GC 和 Full GC区别&#xff1f; Minor GC、Major GC和Full GC是垃圾回收中的三个重要概念&#xff0c;它们描述了垃圾回收的不同阶段和范围&#xff1a; Minor GC&#xff08;新生代GC&#xff09;&#xff1a; Minor GC主要关注清理年轻代&#xff08;Young …

ansible处理多台机器部署基础环境

本次以多台机器需部署zabbix客户端为例&#xff1a; 机器先做免密互信&#xff0c;ansible主机上执行ssh-keygen,一路回车&#xff0c;然后将公钥发送给需管理的主机&#xff1a; ssh-copy-id rootIP 1、编辑hosts文件&#xff0c;添加需配置的主机IP&#xff0c;并测试连通…

LC每日一题记录 2861. 最大合金数

题干 思路 所有合金都需要由同一台机器制造&#xff0c;因此我们可以枚举使用哪一台机器来制造合金。 对于每一台机器&#xff0c;我们可以使用二分查找的方法找出最大的整数 xxx&#xff0c;使得我们可以使用这台机器制造 xxx 份合金。找出所有 xxx 中的最大值即为答案。 代…

鸿蒙ArkUI 宫格+列表+HttpAPI实现

鸿蒙ArkUI学习实现一个轮播图、一个九宫格、一个图文列表。然后请求第三方HTTPAPI加载数据&#xff0c;使用了axios鸿蒙扩展库来实现第三方API数据加载并动态显示数据。 import {navigateTo } from ../common/Pageimport axios, {AxiosResponse } from ohos/axiosinterface IDa…

C语言入门(二)、每日Linux(三)——gcc命令,通过gcc命令熟悉C语言程序实现的过程

使用gcc编译C语言程序 C语言程序实现的过程gcc命令基础用法常用选项编译和汇编选项&#xff1a;优化选项&#xff1a;调试选项&#xff1a;链接选项&#xff1a;警告选项&#xff1a; 实验对于-o选项 通过gcc命令熟悉C语言程序的执行过程1.预处理2.编译阶段3.汇编阶段4.链接阶段…

Atlassian 停服 Bitbucket?三步快速迁移至极狐GitLab

之前的文章Jira 母公司全面停服 Server 产品&#xff0c;用户如何迁移至极狐GitLab提到了 Atlassian 将在 2 月 15 日以后停止对 Server 端产品的服务支持&#xff0c;此后用户将无法像之前一样继续使用 Jira、Bitbucket、Bamboo、Confluence 这些产品了。如果用户想要继续使用…

【QT+QGIS跨平台编译】之十三:【giflib+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、giflib介绍二、文件下载三、文件分析四、pro文件五、编译实践一、giflib介绍 GIFlib(又称为Libgif)是一个开源的C语言库,用于处理GIF图像格式。它提供了一组函数和工具,使得开发者可以读取、写入和操作GIF图像文件。 GIFlib支持GIF87a和GIF89a两种版本的GIF格…

Unity应用在车机上启动有概率黑屏的解决方案

问题描述 最近将游戏适配到车机上&#xff08;Android系统&#xff09;&#xff0c;碰到了一个严重bug&#xff0c;启动的时候有概率会遇到黑屏&#xff0c;表现就是全黑&#xff0c;无法进入Unity的场景。 经过查看LogCat日志&#xff0c;也没有任何报错&#xff0c;也没有任…

智慧交通的“大脑”与“神经”:物联网与车联网双轮驱动,智慧交通加速驶入未来

目录 一、物联网&#xff1a;智慧交通的“大脑” 二、车联网&#xff1a;智慧交通的“神经” 三、物联网与车联网的协同发展 四、智慧交通的未来展望 五、物联网与车联网在智慧交通中的应用案例 六、智慧交通面临的挑战与解决方案 七、政策与法规在智慧交通发展中的作用…

【数据库】聊聊explain如何优化sql以及索引最佳实践

在实际的开发中&#xff0c;我们难免会遇到一些SQL优化的场景&#xff0c;虽然之前也看过周阳的课程&#xff0c;但是一直没有进行细心的整理&#xff0c;所以本篇会进行详细列举explain的相关使用&#xff0c;以及常见的索引最佳实践&#xff0c;并通过案例进行讲解。 数据准…