C++常用的容器:vector、string、deque、stack、queue、list、set、map、hash_set、hash_map等的介绍

目录

1 容器:

2 vector容器:

3 string容器 

4  deque容器

5 stack容器

6 queue 容器

7 list容器 

8 set和multiset容器

9 pair对组 

10 map/multimap容器

11 hash_set

12 hash_map

1 容器:

  在C++中容器是标准模板库STL的六大组件之一,主要用于存放数据,常用的容器有vector、string、deque、stack、queue、list、set、map。

2 vector容器:

        属于序列式容器(容器元素可有序)。容器位于连续内存空间,容器容量大于等于实际大小size。

  

1、vector:单端数组,数组为静态空间,vector可动态扩展
2、vector:动态扩展是指寻找更大的内存空间,将原来数据拷贝到新空间,释放原来空间

3、vector构造函数
        vector<T> v; 采用模板类实现,默认构造,T为数据类型可为内置类型和自定义类型
        vector(v.begin(),v.end()); 将区间[v.begin(),v.end())的元素拷贝给本身
        vector(n,elem);n个elem拷贝给本身
        vector(const vector &v);拷贝构造:vector<int>v3;vector<int>v4(v3);

4、赋值
        重载等号:v3=v4
        assign(begin,end)
        assign(10,100)

5、容器容量、尺寸
        empty();判断容器是否为空
        capacity();容量
        size();尺寸
        resize(int num);重新指定容器长度,默认值填充,若容器变短则删除超出长度的元素
        resize(int num,elem);重新指定容器长度,elem填充,若容器变短则删除超出长度的元素

6、插入和删除
        v.push_back(elem).尾部插入elem元素
        v.pop_back(),尾部删除一个元素
        v.insert(迭代器 pos,elem),在指定迭代器位置pos插入elem
        v.insert(迭代器 pos,n,elem),在指定迭代器位置pos插入n个elem
        v.erase(迭代器 pos),删除迭代器指向的元素
        v.erase(迭代器 start,迭代器 end),删除区间内的元素
        v.clear(),删除所有元素

7、数据存取
        v.at(i)
        重载[].v[i]访问
        v.front(),返回第一个元素
        v.back(),返回最后一个元素

8、容器交换
        swap()
        匿名对象使用完后系统回收空间,利用匿名对象和swap() vector<int>(v).swap(v)
        可以收缩内存

9、预留空间:当容器存储大量数据时并不是一次性扩展数组长度,而是多次扩展
        v.reserve(int len);为容器v预留len个长度的空间,不进行初始化,
        用途:减少vector在动态扩展容量时的扩展次数

3 string容器 

string 是C++风格的字符串内部维护char*,char*是一个指针
1 string 构造函数

        string  s();----默认创建一个空字符串s

        string  s1(const char* s);----使用字符串s 初始化s1

        string  s2(const &string s1);----深拷贝构造,将s1拷贝到s2
        string  s3(int n,char c);----使用n个字符c初始化s3

2 string赋值

函数原型:重载= ;方法assign()
        string& operator=(const char* s)//char*类型字符串赋值给当前字符串;string s1;s1="Hello,World"
        string& operator=(const string &s)//把字符串s赋值给当前字符串;string s2=s1
        string& operator=(char c)//字符c赋值给当前字符串;string s3='d'
        string& assign(const char* s)//把字符串s赋值给当前字符串;string s4;s4.assign(s3)
        string& assign(const char* s,int n)//把字符串s 的前n个字符赋值给当前字符串
        string& assign(const string s)//把字符串s赋值给当前字符串
        string& assign(int n, char s)//用n个字符s赋值给当前字符串

3 拼接

主要有+=、append()方法

        string s1; s1='I';s1+=" love everyday";输出:I love everyday

        string s2;s2.append(s1,2)将s1的前2个字符之外的字符追加到s2

        string s3.append(''I can do it",5)将"I can do it"的前5个字符串追加到s3

4、查找
        str.find("abd"),如果有该字符串返回其索引,没有返回-1

5、替换
        str.replace(1,3,"1111"),将str的1-3位置全替换为"1111"

6、字符串比较

        str1.compare(str2),对比ASCII码,返回0/1/-1代表等于、大于、小于

7、string字符串存取:

        下标[i]或at(i)访问字符串的元素

8、插入和删除

        插入str.insert(1,"add"),从位置1起插入add
        删除:str.erase(1,3),从位置1起删除3个元素

9、子串截取:string str1.substr(int pos=1,int npos=4)从位置pos截取到npos,返回截取字符串        

4  deque容器

        deque容器:双端数组,没有容量概念,内部以分段连续空间存储。其迭代器为非普通指针,较vector容器复杂,因此非必要不选deque,选vector。

         迭代器维护:cur(迭代器所指缓冲区的当前元素)、first(迭代器所指缓冲区的头)、last(迭代器所指缓冲区的尾)、node(当前缓冲区在中控器map的对应节点)。

deque容器:可对头部和尾部操作,deque容器由中控器(所谓的map,非容器map)操作(map存放分段连续空间的指针;map:一小块连续空间,map中每个元素都为一个指针,指向一块连续的缓冲区,这些缓冲区存放deque的元素)。

1、构造

        deque<T,alloc,8>d1(10,5)缓冲区大小8个元素,令其保留10个元素空间,每个元素初值为5

        deque<T>d2(d1) 

2、赋值:

        重载=;operator=  ;

        d.assign();和vector容器相同

3、大小,扩充

deque容器可不断扩充,没有容量限制
        d.size()返回容器大小
        d.empty()判断容器是否为空
        d.resize(num);重新指定容器长度为num,若变长默认填充
        d.resize(num,elem);elem填充

4、插入和删除
两端操作
        d.push_back(elem);容器尾部添加elem
        d.push_front(elem);容器头部添加elem
        d.pop_back();容器尾部删除一个数据
        d.pop_front();容器头部删除一个数据
指定位置操作
        d.insert(pos,elem);pos位置插入elem的拷贝,返回新数据的位置
        d.insert(pos,n,elem);pos位置插入n个elem,无返回值
        d.insert(pos,begin,end);pos位置插入区间[begin,end)的元素,无返回
        d.clear();清空
        d.erase(beg,end);删除区间[beg,end)的数据,返回下一个数据的位置
        d.erase(pos);删除pos位置的数据,返回下一个数据的位置

5、数据存取
        d.at(i);d[i]
        第一个元素d.front();最后一个元素d.back()

6、排序

        sort(d.begin(),d.end());对区间begin和end之间的元素排序;
        支持随机访问的容器都可使用sort()算法

5 stack容器

        实际上是一种容器配接器,底层由其它容器组成,只是调用接口实现为先进后出,只在栈顶操作元素,不提供迭代器。 

stack栈容器:先进后出;只能在栈顶操作,它只有一个出口

1、构造函数、常用接口

        stack<T>s;

        s.push(elem),将元素elem入栈

        s.pop();从栈顶删除一个元素

        s.top();//返回栈顶元素
void test01()
{
    stack<int>stk1;
    stk1.push(1);
    stk1.push(2);
    stk1.push(3);
    stack<int>stk2(stk1);

    int size = stk1.size();
    cout << "stk1的大小:" << size << endl;

    stk1.pop();//从栈顶删除一个元素
    int t_elem=stk2.top();//返回栈顶元素
    cout <<"stk2的栈顶元素:"<< t_elem << endl;
    //查看栈中所有元素,出栈
    while (!stk2.empty())
    {
        cout << stk2.top() << " ";
        stk2.pop();
    }
    cout << endl;
}

int main()
{
    test01();
}

6 queue 容器

        底层由其它容器实现,允许队头和队尾操作,是一种容器配接器,不提供迭代器。 

queue队列,先进先出,队尾入队,队头出队
1.q.push(elem)入队;q.pop()出队,从队头删除一个元素
2、q.front()返回对头元素;q.back()返回队尾元素
3、q.empty()判断是否为空
4、q.size()返回大小 

7 list容器 

        序列式容器,容器内存为非连续内存空间,利于插入和删除。 

list 链表:每个节点分为数据域和指针域,指针域指向存放的下一个节点
链表空间不连续,因此迭代器只支持前移和后移;
优点:可在任意位置快速插入或删除元素,不会造成内存溢出和浪费
缺点:遍历慢,地址不连续,占用空间大
STL中的链表是双向循环链表

1、list构造
        list<T>lst;默认
        list<int>lst;lst(beg,end);将某容器beg-end位置区间的元素赋值给lst

        list<T>lst(n,elem);

        list(const list &lst)拷贝构造

2、赋值和交换

        lst.assign(n,elem);
        lst.assign(beg,end);
重载=
       lst1.swap(lst),lst1与lst元素交换

3、大小:L.size()
        L.resize(n);L.resize(n,elem);修改大小
        L.empty();判断是否为空

4、插入和删除元素
        L.push_back(elem);L.push_front(elem);尾部和头部插入elem
        L.pop_back();L.pop_front();尾部和头部删除
        L.insert(pos,elem);pos位置插入elem,返回插入后的数据位置
        L.insert(pos,n,elem);pos位置插入n个elem,无返回
        L.insert(pos,beg,end);pos位置插入区间[beg,end)的元素,返回下一数据位置
        L.clear();清除
        L.erase(pos);删除pos位置的元素
        L.erase(beg,end);删除区间[beg,end)的元素
        L.remove(elem);删除容器中所有与elem值匹配的元素

5、存取
        L.front();返回第一个元素
        L.back();返回最后一个元素
        不支持随机访问:不支持at(i)和[i]访问

7、反转:reverse()
8、排序:sort()

9、移除连续相同元素,只剩一个该元素:unique()

10、接合,将连续范围的元素移到某个点之前:splice(position,list)

12、合并有序链表:L1.merge(L2)

8 set和multiset容器

        set的所有元素会按键值自动排序,不允许有重复值,其任一元素的值不可变。STL提供了一组set/multiset的集合操作:交集、联集 、差集

        set底层由RB-tree组成。multiset允许有重复键值。

1、set集合,按顺序存储,不允许有重复元素;multiset可插入重复值其他并无差别
2、插入数据只有insert形式,s.insert(elem)
3、交换s1.swap(s2);

4、大小s.size();
5、删除:

        s.erase(pos)/s.erase(elem)/s.erase(beg,end)
        s.clear()清除
6、查找

        s.find(key)若找到返回该元素的迭代器,若不存在返回set.end()
7统计:

        count(key)统计key的元素的个数

9 pair对组 

pair对组,返回一对数据
创建方式:

        1、pair<type,type> p(n1,n2);
        2、pair<type,type>p=make_pair(n1,n2) 

10 map/multimap容器

        map的所有元素都会按照键值自动排序,其元素由实值和键值组成。不允许有相同的键值。 multimap允许有重复键值,其它和map相同。

map中的所有元素都是pair对组;
pair中的第一个元素为键key值,起到索引的作用,第二个值是value为实值;
map中的元素会根据键值自动排序,为关联式容器,底层由二叉树实现
map与multimap区别,multimap允许key值有重复值

1、m.size()返回容器大小,容器中元素数目
2、m.empty()判断容器是否为空
3、m1.swap(m2);交换两个容器

4、打印遍历
template<class T1,class T2>
void printMap(map<T1, T2>& m)
{
    for (map<T1,T2>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key值:" << it->first << "  value值:" << it->second << endl;
    }
    cout << endl;
}

5、m.find(key);返回该元素的迭代器
6、m.count(key);返回该元素的个数
7、排序,默认按key值从小到大排序sort,可以利用仿函数制定排序规则

8、插入m.insert(elem)
9、删除m.erase(pos);删除pos迭代器所指的元素,返回下一个元素的迭代器
10、m.erase(beg,end);删除区间[beg,end)之间的所有元素,返回下一个元素的迭代器
11、m.clear();清除所有元素
12、m.erase(key);删除容器中键为key的元素

11 hash_set

        底层以hashtable实现,元素不会自动排序。使用方式和set相同,不允许键值有重复。

1 构造:hash_set<int>S; 元素为整形

2 hash_set<const char*,hash<const char*>,eqstr> S;元素为字符串,eqstr是自定义的字符比较结构体。

12 hash_map

      底层以hashtable实现,元素不会自动排序。使用方式和set相同,不允许键值有重复。

      此外hash_multiset\hash_multimap分别与multiset和multimap的差别是元素不会自动排序

 本文是作者在学习C++容器时的笔记总结,方便以后查阅。

  • 11
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冲冲冲@chong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值