c++顺序容器内部实现

本文详细介绍了C++中三种常见容器:vector、list、deque的内部实现机制,包括它们的优势、劣势及在不同场景下的应用。重点对比了三种容器在内存管理、数据访问效率、插入与删除操作等方面的特性。

1、vector、list、deque的内部实现机制?

vector:vectorbuilt-in数组类似,是一个在堆上建立的一维数组,它拥有一段连续的内存空间,并且起始地址不变,因此它能非常好的支持随即存取,即[]操作符。vector因为存储在堆上,所以支持erase( ), resieze()(重新划分容器容量)等操作; vector不用担心越界当空间不够用的时候,系统会自动按照一定的比例(对capacity( )大小)进行扩充。在vector序列末尾添加(push_back( ))或者删除(pop_back( ))对象效率高,在中间进行插入或删除效率很低,主要是要进行元素的移动和内存的拷贝,原因就在于当内存不够用的时候要执行重新分配内存,拷贝对象到新存储区,销毁old对象,释放内存等操 作,如果对象很多的话,这种操作代价是相当高的。为了减少这种代价,使用vector最理想的情况就是事先知道所要装入的对象数目,用成员函式 reserve( )预定下来;vector最大的优点莫过于是检索(用operator[ ])速度在这三个容器中是最快的,

a、vector为了支持快速的随机访问,容器中的元素以连续的方式进行存放——每一个元素都紧挨着前一个元素进行存储;

b、当往容器内添加一个新的元素时,如果容器中没有空间容纳新的元素,此时,由于元素必须连续存储以便索引访问,所以不能在内存中随便找个地方存储这个心元素。于是,vector必须重新分配存储空间,用来存放原来的元素以及新添加的元素:存放在旧存储卡就中的元素被复到新存储空间里,借着插入新元素,最后撤销旧的存储空间。为了实现vector容器的快速内存分配,在实际分配过程中的容量要比当前所需的空间多一些,vector容器预留出这些额外的存储区,用于存放心添加的元素。于是,不必为每一个新元素重新分配容器。(以最小的代价连续存储元素从而带来访问元素的遍历以弥补其存储空间代价)

c、由于vector进行连续存储,所以在vector里面需要定义一个容量capacity的概念,vector的size指的是当前容器中所具有的元素的个数,而capacity则指的是容器在需要重新分配内存空间前所能存储的元素总数,reserve则表示容器需要预留多少个元素的存储空间。capacity>=size,标准库中提供了reserve和capacity函数,程序员可以自己定义额外的存储空间或者容量。当vector的当前容量已经被消耗完全的时候,容器不得不分配新的存储空间,以加倍当前容量的分配策略是先重新分配。当然,vector的每种是先可自由选择内存分配策略,必要时才进行分配,分配多少内存取决于其具体的实现方式。

例程如下:

1、初始化部分

vector< int > ivec;

cout  << ivec.size() << << ivec,capacity() << endl;

for( vector< int >::size_type ix = 0;ix != 24;++ix) 

    ivec.push_back(i);

cout  << ivec.size() << << ivec,capacity() << endl;

输出结果: 0  0           24  32

2、预留额外空间

ivec.reserve(50);

cout << ivec.size() << ivec.capacity() << endl;

while(ivec.size() != ivec.capacity())

    ivec.push_back(0);

cout << ivec.size() << << ivec,capacity() << endl;

输出结果:24  50        50  50

3、重新分配空间

ivec.push_back(42);

cout << ivec.size() << << ivec,capacity() << endl;

输出结果:51  100


list: list的本质是一个双向链表(根据sgi stl源代码),内存空间不连续,通过指针进行操作。说道链表,它的高效率首先表现是插入,删除元素,进行排序等等需要移动大量元素的操作。显然链表没有检索操作operator[ ], 也就是说不能对链表进行随机访问,而只能从头至尾地遍历,这是它的一个缺陷。list有不同于前两者的某些成员方法,如合并list的方法splice( ), 排序sort( ),交换list 的方法swap( )等等。

a、不支持下标操作

b、当往容器内添加一个新的元素时,标准库只需要创建一个新的元素,然后将新元素连接在已存在的链表中,不需要重新分配存储空间,也不必复制任何已经存在的元素。


deque:deque 是一个double-ended queue是由多个连续内存块构成,deque是list和vector的兼容,分为多个块,每一个块大小是512字节,块通过map块管理,map块里保存每个块得首地址。因此该容器也有索引操作operator[ ],效率没vector高。另外,dequevector多了push_front( ) & pop_front( )操作。在两端进行此操作时与list的效率差不多。


2、顺序容器之间的比较?

a、vector和deque支持下标操作,list不支持下标操作

b、vector和deque容器均提供了对元素的快速随机访问,但是在容器的任意位置插入或者删除元素,避灾容器尾部插入和删除开销更大;而list类型在任何位置都能快速插入和删除,但是元素的随机访问开销较大

c、deque容器与vector容器在与deque的数据结构更为复杂,deque容器同时提供了高效的在其首部insert和erase操作,就如同在尾部进行操作一样

d、在deque容器首尾部插入元素不会使任何迭代器失效,而在首部uozhe尾部删除元素则只会使指向被删除元素的迭代器失效,在其他的任何位置删除或者插入都会使该容器的所有迭代器失效


一、数据采集层:多源人脸数据获取 该层负责从不同设备 / 渠道采集人脸原始数据,为后续模型训练与识别提供基础样本,核心功能包括: 1. 多设备适配采集 实时摄像头采集: 调用计算机内置摄像头(或外接 USB 摄像头),通过OpenCV的VideoCapture接口实时捕获视频流,支持手动触发 “拍照”(按指定快捷键如Space)或自动定时采集(如每 2 秒采集 1 张),采集时自动框选人脸区域(通过Haar级联分类器初步定位),确保样本聚焦人脸。 支持采集参数配置:可设置采集分辨率(如 640×480、1280×720)、图像格式(JPG/PNG)、单用户采集数量(如默认采集 20 张,确保样本多样性),采集过程中实时显示 “已采集数量 / 目标数量”,避免样本不足。 本地图像 / 视频导入: 支持批量导入本地人脸图像文件(支持 JPG、PNG、BMP 格式),自动过滤非图像文件;导入视频文件(MP4、AVI 格式)时,可按 “固定帧间隔”(如每 10 帧提取 1 张图像)或 “手动选择帧” 提取人脸样本,适用于无实时摄像头场景。 数据集对接: 支持接入公开人脸数据集(如 LFW、ORL),通过预设脚本自动读取数据集目录结构(按 “用户 ID - 样本图像” 分类),快速构建训练样本库,无需手动采集,降低系统开发与测试成本。 2. 采集过程辅助功能 人脸有效性校验:采集时通过OpenCV的Haar级联分类器(或MTCNN轻量级模型)实时检测图像中是否包含人脸,若未检测到人脸(如遮挡、侧脸角度过大),则弹窗提示 “未识别到人脸,请调整姿态”,避免无效样本存入。 样本标签管理:采集时需为每个样本绑定 “用户标签”(如姓名、ID 号),支持手动输入标签或从 Excel 名单批量导入标签(按 “标签 - 采集数量” 对应),采集完成后自动按 “标签 - 序号” 命名文件(如 “张三
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值