【C++】C++STL容器知识点小结

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 【C++】C++STL容器知识点小结

STL主要分为分为三类:

  • algorithm(算法) - 对数据进行处理(解决问题) 步骤的有限集合
  • container(容器) - 用来管理一组数据元素
  • Iterator (迭代器) - 可遍历STL容器内全部或部分元素”的对象

容器和算法通过迭代器可以进行无缝地连接。在STL中几乎所有的代码都采用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。

STL 最早源于惠普实验室,早于C++存在,但是C++引入STL概念后,STL就成为C++的一部分,因为它被内建在你的编译器之内,不需要另行安装。

STL被组织为下面的13个头文件:

< algorithm > < memory >
< deque > < numeric >
< functional > < queue >
< iterator > < set >
< vector > < stack >
< list > < utility >
< map >

容器

在实际的开发过程中,数据结构本身的重要性完全不逊于算法的重要性,当程序中存在着对时间要求很高的部分时,数据结构的选择就显得更加重要。

经典的数据结构数量有限,但是在项目实战中,我们常常重复着一些为了存放不同数据类型而实现顺序表、链表等结构而重复编写的代码,这些代码都十分相似,只是为了适应不同数据类型的变化而在细节上有所出入。STL容器就为我们提供了这样的方便,它允许我们重复利用已有的实现构造自己的特定类型下的数据结构,通过设置一些模板,STL容器对最常用的数据结构提供了支持,这些模板的参数允许我们指定容器中元素的数据类型,避免重复编码。

容器部分主要有由< vector >,< list >,< deque >,< set >,< map >,< stack > 和< queue >组成。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ck0IEaTK-1632886528523)(01SLT.assets/image-20210927103557400.png)]

容器的访问方式:
下标访问、迭代器访问(iterator)

容器的存储将原来的数据拷贝一份(存放指针即可解决这个问题)。给这个类定义一个拷贝构造函数,看是否调用即可验证。

vector

vector是一个将元素置于动态数组中加以管理的容器。

vector可以随机存取元素,支持索引值直接存取, 用[]操作符或at()方法对元素进行操作。

vector尾部添加或移除元素非常快速。但是在中部或头部插入元素或移除元素比较费时

容量capacity要比真是的数据个数size大1。


当使用vector的默认构造函数(vector< int >v1),不能直接通过下标访问,空间还没开辟。

vector带参构造函数

vector< int >v2(存储元素个数,默认存储元素的数值);
例如:
vector<int>v2(10);
构造时就分配空间,同时插入默认元素0
指定容器中存储的元素个之后,此时该vector的容量和大小相等。    
(用默认vector的默认构造函数之后再往里面push_back的话,vector会自动开辟空间4个4个的扩容。)

赋值

vector<int>v3(v2);
vector<int>v4(v3.begin.() + x,v3.end());
int test[] = { 1,2,3,4,5 };
vector<int>v4(test, test + 3);
v2.assign(2,888);//改变vector中的元素个数和元素值
v2.assign(v3.begin(),v3.end());//使用迭代器赋值
v2.assign(test,test+3);//使用指针赋值 
v2 = v3;//调用赋值运算

大小

vector会自动扩充存储大小。

v2.resize(4);//重新调整v2容器大小,多余的被抹除。不够的以0填充。

v2.resize(18,666);//扩充v2大小,以666填充

如果原来大小就是这么大,则不会发生变化。

尾部的添加和删除

v2.push_back(6);

v2.pop_back();

访问元素

下标访问
    v2[1];

at
    v2.at(1)

接口返回引用
    v2.front();//取到第一个元素
    v2.end();//取到最后一个元素

插入和删除

//插入单个元素
v2.insert(迭代器,插入的数值);
//插入多个元素
v2.insert(v2.begin(),3,888);//在开始的位置插入三个888
v2.insert(v2.begin(),v3.begin(),v3.end());//将v3的内容从v2开始插入进去。

//插入单个元素的时候返回值是一个迭代器
//把整个vector干掉
v2.clear();

//干掉的单个元素
v2.erase(v2.begin()+1);

//干掉多个元素
v2.erase(v2.begin(),b2.begin()+1);//不包括结尾,“左闭右开”

//删除单个元素返回值也是个迭代器

deque

deque是“double-ended queue”的缩写,和vector一样都是STL的容器,唯一不同的是:

deque是双端数组,而vector是单端的。

Deque 特点

  • deque在接口上和vector非常相似,在许多操作的地方可以直接替换。
  • deque可以随机存取元素(支持索引值直接存取,用[]操作符或at()方法)
  • deque头部和尾部添加或移除元素都非常快速, 但是在中部安插元素或移除元素比较费时。

使用时,包含头文件:#include < deque >

(deque使用多个数组实现)

对比

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MjNBec1N-1632886528524)(01SLT.assets/image-20210927155900584.png)]

​ 多数操作同vector

deuqe可以快速在头部和尾部进行添加或者移除

deque.push_back(element);    //容器尾部添加一个数据
deque.push_front(element);    //容器头部插入一个数据
deque.pop_back();            //删除容器最后一个数据
deque.pop_front();            //删除容器第一个数据

deque的数据存取
  1. 使用下标操作 deqIntA[0] = 100;
  2. 使用at 方法 如: deqIntA.at(2) = 100;
  3. 接口返回的引用 deqIntA.front() 和 deqIntA.back()

    注意: 第一和第二种方式必须注意越界


end()返回的是一个指向最后一个元素之后位置的迭代器,就类似于字符串结束符。


deque与迭代器
deque.begin();  //返回容器中第一个元素的迭代器。

deque.end();  //返回容器中最后一个元素之后的迭代器。

deque.rbegin();  //返回容器中倒数第一个元素的迭代器。

deque.rend();  //返回容器中倒数最后一个元素之后的迭代器。

deque.cbegin();  //返回容器中第一个元素的常量迭代器。

deque.cend();  //返回容器中最后一个元素之后的常量迭代器。

常量迭代器只能访问呢元素,不能修改元素。


deque的赋值
deque.assign(beg,end);    //将[beg, end)区间中的数据拷贝赋值给本身。注意该区间是左闭右开的区间。
deque.assign(n,elem);  //将n个elem拷贝赋值给本身。
deque& operator=(const deque &deq);    //重载等号操作符 
deque.swap(deq);  // 将deque与本身的元素互换

deque的大小
deque.size();              //返回容器中元素的个数

deque.empty();      //判断容器是否为空

deque.resize(num);      //重新指定容器的长度为num,若容器变长,则以默认值0填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。

deque.resize(num, elem);  //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。

deque的插入
deque.insert(pos,elem);  //在pos位置插入一个elem元素的拷贝,返回新数据                            的位置。

deque.insert(pos,n,elem);  //在pos位置插入n个elem数据,无返回值。

deque.insert(pos,beg,end);  //在pos位置插入[beg,end)区间的数据,无返回值
deque的删除
deque.clear();       //移除容器的所有数据

deque.erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。

deque.erase(pos);   //删除pos位置的数据,返回下一个数据的位置。

注意迭代器遍历删除

删除一个元素该位置的元素是会前移的。

for(deque<int>::iterator it = deqIntA.begin(); it!=deqIntA.end();){
        if(*it == 4){
            //接收-返回指向下一个位置的迭代器
            it = deqIntA.erase(it);
        }else {
            cout<<*it;
            cout<<" ";
            it++;
        }
    }

list

list是一个双向链表容器,可高效地进行插入删除元素。

List 特点:

  • list不可以随机存取元素,所以不支持at.(position)函数与[]操作符。可以对其迭代器执行++,但是不能这样操作迭代器:it+3。

    即:list的迭代器不能加数字,但可以通过多次自增达到效果。

  • 使用时包含 #include < list >

list对象的默认构造

list同样采用模板类实现,对象的默认构造形式:list<T> listT;  如:

list<int> lstInt;       //定义一个存放int的list容器。

list<float> lstFloat;     //定义一个存放float的list容器。

list<string> lstString;    //定义一个存放string的list容器。

注意:尖括号内还可以设置指针类型或自定义类型。


vector的内存空间是预先分配的。

list不存在capacity方法,所以它并没有提前分配空间。


list对象的带参数构造

方式一:list(beg,end);   //将[beg, end)区间中的元素拷贝给本身。方式二:list(n,elem);    //构造函数将n个elem拷贝给本身。方式三:list(const list &lst); //拷贝构造函数。

list头尾的添加移除操作

方式一:list(beg,end);   //将[beg, end)区间中的元素拷贝给本身。

方式二:list(n,elem);    //构造函数将n个elem拷贝给本身。

方式三:list(const list &lst); //拷贝构造函数。

list的数据存取

list.front();   //返回第一个元素。
list.back();  //返回最后一个元素。

list与迭代器

list.begin();     //返回容器中第一个元素的迭代器。

list.end();      //返回容器中最后一个元素之后的迭代器。

list.rbegin();     //返回容器中倒数第一个元素的迭代器。

list.rend();     //返回容器中倒数最后一个元素的后面的迭代器。

list.cbegin();  //返回容器中第一个元素的常量迭代器。

list.cend();  //返回容器中最后一个元素之后的常量迭代器。

list的赋值

list.assign(beg,end);   //将[beg, end)区间中的数据拷贝赋值给本身。

list.assign(n,elem);  //将n个elem拷贝赋值给本身。

list& operator=(const list &lst);    //重载等号操作符。

list.swap(lst);  // 将lst与本身的元素互换。

list的大小

ist.size();      //返回容器中元素的个数

list.empty();      //判断容器是否为空

list.resize(num);  //重新指定容器的长度为num,若容器变长,则以默认值0填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。

list.resize(num, elem);  //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。

list的插入

list.insert(pos,elem);  //在pos位置插入一个elem元素的拷贝,返回新数据的位置。

list.insert(pos,n,elem);  //在pos位置插入n个elem数据,无返回值。

list.insert(pos,beg,end);  //在pos位置插入[beg,end)区间的数据,无返回值。

list的删除

list.clear();        //移除容器的所有数据

list.erase(beg,end);  //**删除****[beg,end)**区间的数据,返回下一个数据的位置。

list.erase(pos);   //删除pos位置的数据,返回下一个数据的位置。

lst.remove(elem);  //删除容器中所有与elem值匹配的元素。

vector和deque中没有remove操作

list的反序排列

l list.reverse();   //反转链表,比如list包含1, 2, 3, 4, 5五个元素,运行此方法后,list就包含5, 4, 3, 2, 1元素。

set/multiset

set/multiset容器概念

set和multiset是一个集合容器,其中set所包含的元素是唯一的,集合中的元素按一定的顺序排列。set采用红黑树变体的数据结构实现,红黑树属于平衡二叉树。在插入操作和删除操作上比vector快。在n个数中查找目标数的效率是 log2 n 。


C++11新特性:变参模板、完美转发和empalce——C++11新特性:变参模板、完美转发和emplace


红黑树定义

是每个节点都带有颜色属性(颜色为红色或黑色)的自平衡二叉查找树,满足下列性质:

  1. 节点是红色或黑色
  2. 根节点是黑色
  3. 所有叶子节点都是黑色节点(NULL)
  4. 每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节点。
  5. 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GkQk2uma-1632886528526)(01SLT.assets/image-20210928091221639.png)]

set 和 multiset 特点

  1. set中元素插入过程是按排序规则插入(自动排序),所以不能指定插入位置
  2. set不可以直接存取元素。(不可以使用at.(pos)与[]操作符)。
  3. multiset与set的区别:set支持唯一键值,每个元素值只能出现一次;而multiset中同一值可以出现多次
  4. 不可以直接修改set或multiset容器中的元素值,因为该类容器是自动排序的。如果希望修改一个元素值,必须先删除原有的元素,再插入新的元素。

头文件 #include < set >

set/multiset对象的默认构造

set<int> setInt;        //一个存放int的set容器。

set<float> setFloat;      //一个存放float的set容器。

set<string> setString;     //一个存放string的set容器。

multiset<int> mulsetInt;       //一个存放int的multi set容器。

multiset<float> multisetFloat;    //一个存放float的multi set容器。

multiset<string> multisetString;   //一个存放string的multi set容器。

set/multiset 对象的带参构造函数

set(beg,end);   //将[beg, end)区间中的元素拷贝给本身。

set(const set &s); //拷贝构造函数。

multiset(beg,end);   //将[beg, end)区间中的元素拷贝给本身。

multiset(const multiset &s); //拷贝构造函数。

set对象的拷贝构造与赋值

set(const set &st);            //拷贝构造函数

set& operator=(const set &st);    //重载等号操作符

set.swap(st);                  //交换两个集合容器

仿函数(函数对象)——C++仿函数(函数对象)(STL重点)


set的插入和pair的用法

pair表示一个对组,它将两个值视为一个单元,把两个值捆绑在一起。

pair<T1,T2>用来存放的两个值的类型,可以不一样,也可以一样,如T1为int,T2为float。T1,T2也可以是自定义类。

pair.first是pair里面的第一个值,是T1类型。

pair.second是pair里面的第二个值,是T2类型。

set容器的insert的返回值是一个对组
pair<set<int>::iterator,bool >ret = s1.insert(5);
cout<<*(ret.first)<<endl;
cout<<ret.second<<endl;
first返回插入元素的迭代器,*它得到的就是这个数值

set与迭代器

set.insert(elem);   //在容器中插入元素。

set.begin();     //返回容器中第一个数据的迭代器。

set.end();      //返回容器中最后一个数据之后的迭代器。

set.rbegin();     //返回容器中倒数第一个元素的迭代器。

set.rend();     //返回容器中倒数最后一个元素的后面的迭代器。

注意循环遍历删除的时候it++的位置。

set/multiset的大小

set.size();    //返回容器中元素的数目

set.empty();//判断容器是否为空

注意事项: 它们没有resize 方法

set/multiset的删除

set.clear();         //清除所有元素

set.erase(pos);   //删除pos迭代器所指的元素,返回下一个元素的迭代器。

set.erase(beg,end);     //删除区间[beg,end)的所有元素,返回下一个元素的迭代器。

set.erase(elem);   //删除容器中值为elem的元素。

删除区间内的某个或某些元素

setInt是用set<int>声明的容器,假设它内部现已包含按顺序的1, 2, 3, 4, 5, 6元素。

set<int>::iterator itBegin=setInt.begin();

++ itBegin;

set<int>::iterator itEnd=setInt.begin();

++ itEnd;

++ itEnd;

++ itEnd;

setInt.erase(itBegin,itEnd);

//此时容器setInt包含按顺序的1, 4, 5, 6四个元素。

删除容器中第一个元素

setInt.erase(setInt.begin());    

删除容器中值为x的元素

setInt.erase(5); 

删除setInt的所有元素

setInt.clear();            //容器为空

set/multiset的查找

set.find(elem);  //查找elem元素,返回指向elem元素的迭代器。
//find是否查找到元素,可以通过返回的迭代器和容器的end()方法进行比较。end()就相当于字符串结束符,返回最后一个元素后面位置的迭代器。


set.count(elem);  //返回容器中值为elem的元素个数。对set来说,要么是0,要么是1。对multiset来说,值可能大于1。

set.lower_bound(elem);  //返回第一个>=elem元素的迭代器。

set.upper_bound(elem);      //  返回第一个>elem元素的迭代器。

set.equal_range(elem);        //返回multiset容器中与elem相等的上下限的两个迭代器。上限是闭区间,下限是开区间,如[beg,end)。这个函数返回两个迭代器,而这两个迭代器被封装在pair中。
 //例如 1 2 3 3 3 4 返回的是[3,6);

map/multimap

map是标准的关联式容器,一个map里存储的元素是一个键值对序列,叫做(key,value)键值对。它提供基于key快速检索数据的能力。

  1. map中key值是唯一的。集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置。
  2. map底层的具体实现是采用红黑树变体的平衡二叉树的数据结构。在插入操作、删除和检索操作上比vector快很多。
  3. map可以直接存取key所对应的value,支持[]操作符,如map[key]=value。

    include

map<int,string>m1;
m1.insert(pair<int,string>(18,"xiaohua"));

multimap与map的区别

map支持唯一键值,每个键只能出现一次;而multimap中相同键可以出现多次。multimap不支持[]操作符。

map/multimap对象的默认构造

map/multimap采用模板类实现,对象的默认构造形式:

map<T1,T2> mapTT; 

multimap<T1,T2>  multimapTT;  

如:

map<int, char> mapA;

map<string,float> mapB;

//其中T1,T2还可以用各种指针类型或自定义类型

map和multimap对象的带参数构造

方式一:map(beg,end); //将[beg, end)区间中的元素拷贝给本身。

方式二:map(const map &mapObject); //拷贝构造函数。

map的插入与迭代器

map.insert(...); //往容器插入元素,返回pair<iterator,bool>

map中插入元素的四种方式

假设 map<int, string> mapStu;

方式一、通过pair的方式插入对象

mapStu.insert( pair<int,string>(1,"张三") );

例如:

map<int, string> m1;
m1.insert(pair<int, string>(18, "王小花"));
pair<map<int,string>::iterator,bool>ret =     m1.insert(pair<int, string>(18, "李小花"));
if (ret.second == 1)
{
    cout << "成功啦" << endl;
}
else
{
    cout << "失败" << endl;
}

方式二、通过pair的方式插入对象

mapStu.inset(make_pair(2, “李四”));

方式三、通过value_type的方式插入对象

mapStu.insert( map<int,string>::value_type(3,"王五") );

方式四、通过数组的方式插入值

如果键值对已经存在则覆盖原值。

mapStu[4] = "赵六";

mapStu[4] = "赵四";覆盖赵六

mapStu[5] = “小七";

(没有数值默认初始化)

注意:

前三种方法,采用的是insert()方法,该方法返回值为pair<iterator,bool>

此三种方式插入重复的键值会插入均会失败。

第四种方法非常直观,但碰到相同的键时会进行覆盖操作。比如插入key 为4的键值时,先在mapStu中查找主键为4的项,若不存在,则将一个键为4,值为默认初始化值的对组插入到mapStu中,然后再将值修改成“赵六”。若发现已存在4这个键,则修改这个键对应的value。

string strName = mapStu[8]; //取值操作或插入操作

l只有当mapStu存在8这个键时才是正确的取操作,否则会自动插入一个实例,键为8,值为默认构造时的初始化值。

迭代器

map.begin();  //返回容器中第一个数据的迭代器。

map.end();  //返回容器中最后一个数据之后的迭代器。

map.rbegin();  //返回容器中倒数第一个元素的迭代器。

map.rend();  //返回容器中倒数最后一个元素的后面的迭代器。

map/multimap 排序

参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jHIHTD1S-1632886528527)(01SLT.assets/image-20210928201038963.png)]

map<T1,T2,less<T1> >  mapA;  //该容器是按键的升序方式排列元素。未指定函数对象,默认采用less<T1>函数对象。

map<T1,T2,greater<T1>> mapB;  //该容器是按键的降序方式排列元素。

less<T1>与greater<T1>  可以替换成其它的函数对象functor。

可编写自定义函数对象以进行自定义类型的比较,使用方法与set构造时所用的函数对象一样。

map对象的拷贝构造与赋值

map(const map &mp);           //拷贝构造函数

map& operator=(const map &mp);    //重载等号操作符

map.swap(mp);                //交换两个集合容器    

map的大小

map.size();    //返回容器中元素的数目

map.empty();//判断容器是否为空

map的删除

map.clear();        //删除所有元素

map.erase(pos);    //删除pos迭代器所指的元素,返回下一个元素的迭代器。

map.erase(beg,end);//删除区间[beg,end)的所有元素    ,返回下一个元素的迭代器。

map.erase(key);   //删除容器中key为key的对组,返回删除的对组个数,失败返回0

map.erase(key_type *first, key_type *last)  //删除数组指定的半闭半开的区间中 特定的key对应的所有队组
例如:
    int range[] = {1,2,3,4};

map/multimap的查找

map.find(key);  查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回map.end();
//因为multimap中可以存在重复的键值,所以用循环迭代器查找的时候,可以输入具有相同键值的元素。
//例如
map<int, string>m1;
m1.insert(pair<int,string>(18, "sb"));
map<int, string>::iterator it = m1.find(18);
if (it != m1.end())
{
    cout << it->first << endl;
    cout << it->second << endl;
}//这个比count控制循环更灵活实用性更强



map.count(key);  //返回容器中键值为key的对组个数。对map来说,要么是0,要么是1;对multimap来说,值>=0。

map.lower_bound(keyElem);  //返回第一个key>=keyElem元素的迭代器。

map.upper_bound(keyElem);      //  返回第一个key>keyElem元素的迭代器。

map.equal_range(keyElem);        //返回容器中key与keyElem相等的上下限的两个迭代器。上限是闭区间,下限是开区间,如[beg,end)。(multimap重复元素    )

最后一个的代码示例
multimap<int, string> mul1;
mul1.insert(pair<int, string>(1, "甲"));
mul1.insert(pair<int, string>(2, "乙"));
mul1.insert(pair<int, string>(2, "丙"));
mul1.insert(pair<int, string>(3, "丁"));
mul1.insert(pair<int, string>(4, "卯"));

//返回的是两个玩意,所以要对组接收
pair<multimap<int, string>::iterator,multimap<int, string>::iterator> RecvPari = mul1.equal_range(2);
if (RecvPari.first != mul1.end())//就相当于对组与对组对比
{
    //注意对应map的元素存放在对组中
    cout << (*RecvPari.first).second << endl;
}
if (RecvPari.second != mul1.end())
{
    //存放value在该对组的第二位
    cout << (*RecvPari.second).second << endl;
}
//输出乙和丁
return 0;

queue

queue简介

  1. queue是队列容器,是一种“先进先出”的容器。
  2. 默认情况下queue是利用deque容器实现的一种容器。
  3. 它只允许在队列的前端(front)进行删除操作,而在队列的后端(back)进行插入操作
  4. include

默认用deque容器实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eB6Amp7a-1632886528529)(01SLT.assets/image-20210929092413249.png)]

可以显式指定类型来控制用什么容器实现

例如:(注意作为内置容器的容器是否与queue兼容)

queue<int,list<int>>;

queue对象的默认构造

queue采用模板类实现,queue对象的默认构造形式:queue<T> queT; 如:
 
queue<int> queueInt;       //一个存放int的queue容器。

queue<float> queueFloat;   //一个存放float的queue容器。

queue<string> queueString;   //一个存放string的queue容器。

...                  
注意: 尖括号内还可以设置指针类型或自定义类型。

queue 对象的带参构造

queue<int, list<int>> queueList; //内部使用list 来存储队列元素的queue 容器.

错误: queue<int, vector<int>> queueList; //内部不能使用vector来存储队列元素                

queue的push()与pop()方法

queue.push(elem);  //往队尾添加元素

queue.pop();    //从队头处移除队首元素

queue对象的拷贝构造与赋值

queue(const queue &que);           //拷贝构造函数

queue& operator=(const queue &que);    //重载等号操作符

queue的数据存取

queue.back();  //返回最后一个元素

queue.front();  //返回第一个元素

可以通过这两个接口修改容器对应内容,因为返回的是引用
 
存放自定义对象的时候考虑queue.emplace

queue的大小

queue.empty();  //判断队列是否为空

queue.size();        //返回队列的大小

优先级队列priority_queue

优先队列: 它的入队顺序没有变化,但是出队的顺序是根据优先级的高低来决定的。优先级高的优先出队。

默认值越大优先级越大。

priority_queue(int,vector<int>,greater<int>);//值越小优先级越大
priority_queue(int,deque<int>,greater<int>);//值越小优先级越大

stack

stack是堆栈容器,是一种"先进后出的容器"。

默认基于deque容器实现的容器。

(如果用vector实现,在前面删除元素涉及到元素的移动,效率不如deque,一般情况下不建议使用vector。)

stack对象的默认构造

stack采用模板类实现, stack对象的默认构造形式: stack <T> stkT;  

stack <int> stkInt;       //一个存放int的stack容器。

stack <float> stkFloat;   //一个存放float的stack容器。

stack <string> stkString;   //一个存放string的stack容器。          

//尖括号内还可以设置指针类型或自定义类型。

stack的push()与pop()方法

stack.push(elem);  //往栈头添加元素

stack.pop();     //从栈头移除第一个元素

//例:
stack<int> stkInt;  
stkInt.push(1);
stkInt.push(2);
stkInt.pop();  
stkInt.push(3);
此时stkInt存放的元素是1, 3

stack对象的拷贝构造与赋值

stack(const stack &stk);           //拷贝构造函数

stack& operator=(const stack &stk);    //重载等号操作符

stack的数据存取

stack.top();     //返回最后一个压入栈元素
//返回的是引用可以修改值

stack的大小

stack.empty();  //判断堆栈是否为空

stack.size();        //返回堆栈的大小

array

C++11新增

array容器概念

array是将元素置于一个固定数组中加以管理的容器。

array可以随机存取元素,支持索引值直接存取,用[]操作符或at()方法对元素进行操作,也可以使用迭代器访问

不支持动态的新增删除操作

array可以完全替代C语言中的数组,使操作数组元素更加安全!

array对象的构造

array采用模板类实现,array对象的默认构造形式(涉及非类型参数-数值类模板)

array<T,10>  arrT;  //10 为数值型模板参数

array<int, 6> a1;   //一个存放int的array容器

array<float, 6> a2;  //一个存放float的array容器

array<student, 6> a3; //一个存放student的array容器


array<int, 6> a1={1,2,3,4,5,6}; //定义时同时初始化

array的赋值

a2.assign(0);//改变原来array中的所有元素的值

array<int, 6> a1 = {1, 2, 3};

array<int, 6> a2 ;

array的大小

array.size();      //返回容器中元素的个数

array.max_size(); //返回容器中最大的元素个数,与size 等同

array.empty();  //判断容器是否为空

array的数据存取

  1. 使用下标操作 a1[0] = 100;
  2. 使用at 方法 如: a1.at(2) = 100;
  3. 接口返回的引用 a2.front() 和 a2.back()
  4. 返回内建数组的指针 a1.data()

注意: 第一和第二种方式必须注意越界

补充

注意:任何时候在模板(template)中使用一个嵌套从属类型名称, 需要在前一个位置, 添加关键字。

(写模板的时候注意)

例如:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tZNUp0e0-1632886528530)(01SLT.assets/image-20210929112319934.png)]

typename list<T>::const_iterator citor;
相关文章
|
2月前
|
存储 算法 C++
C++ STL 初探:打开标准模板库的大门
C++ STL 初探:打开标准模板库的大门
112 10
|
1天前
|
算法 C语言 C++
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
19 7
|
19天前
|
存储 编译器 C语言
【c++丨STL】vector的使用
本文介绍了C++ STL中的`vector`容器,包括其基本概念、主要接口及其使用方法。`vector`是一种动态数组,能够根据需要自动调整大小,提供了丰富的操作接口,如增删查改等。文章详细解释了`vector`的构造函数、赋值运算符、容量接口、迭代器接口、元素访问接口以及一些常用的增删操作函数。最后,还展示了如何使用`vector`创建字符串数组,体现了`vector`在实际编程中的灵活性和实用性。
45 4
|
20天前
|
C语言 C++ 容器
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
45 5
|
20天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
30 2
|
26天前
|
存储 算法 Linux
【c++】STL简介
本文介绍了C++标准模板库(STL)的基本概念、组成部分及学习方法,强调了STL在提高编程效率和代码复用性方面的重要性。文章详细解析了STL的六大组件:容器、算法、迭代器、仿函数、配接器和空间配置器,并提出了学习STL的三个层次,旨在帮助读者深入理解和掌握STL。
42 0
|
5天前
|
存储 编译器 C语言
【c++丨STL】vector模拟实现
本文深入探讨了 `vector` 的底层实现原理,并尝试模拟实现其结构及常用接口。首先介绍了 `vector` 的底层是动态顺序表,使用三个迭代器(指针)来维护数组,分别为 `start`、`finish` 和 `end_of_storage`。接着详细讲解了如何实现 `vector` 的各种构造函数、析构函数、容量接口、迭代器接口、插入和删除操作等。最后提供了完整的模拟实现代码,帮助读者更好地理解和掌握 `vector` 的实现细节。
17 0
|
23天前
|
存储 设计模式 C++
【C++】优先级队列(容器适配器)
本文介绍了C++ STL中的线性容器及其适配器,包括栈、队列和优先队列的设计与实现。详细解析了`deque`的特点和存储结构,以及如何利用`deque`实现栈、队列和优先队列。通过自定义命名空间和类模板,展示了如何模拟实现这些容器适配器,重点讲解了优先队列的内部机制,如堆的构建与维护方法。
31 0
|
2月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
56 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
2月前
|
存储 程序员 C++
C++常用基础知识—STL库(2)
C++常用基础知识—STL库(2)
74 5