C++之容器总结

本文总结了C++中的容器,包括C++11前后的序列容器如deque、list、vector,以及关联容器如set、map、multiset、multimap。详细介绍了各容器的特点、操作和适用场景,特别关注了C++11新增的forward_list和无序关联容器。

C++之容器总结


1、容器种类:序列、关联容器

2、C++11以前的容器:deque 、list、queue、priority_queue、stack、vectormap、multimap 、set、multiset、bitest

3、C++11新增的容器:forward_list、unordered_map、unordered_multimap、unordered_set、unordered_multiset;

4、容器的概念:存储其它对象的对象,被存储的对象必须是同一种类型。

5、时间复杂度:编译时间>固定时间>线性时间(由快到慢)

6、序列:特殊的容器,7种STL容器类型(deque、forward_list 、queue 、priority_queue 、stack 、vector)
在这里插入图片描述

7、序列(容器的详细介绍)

7.1 vector

头文件:

#include<vector>

vector是数组的一种类表示,提供自动内存管理功能,可以动态改变vector对象的长度,可以随着元素的添加和删除而且增大和缩小。提供对元素的随机访问,在尾部添加和删除元素的时间是固定的,但在头部或者中间插入和删除元素的复杂度为线性时间。

vector是可反转容器概念的模型,增加两个类方法:rbegin()和rend(),和bengin()和end()形成对比。

  • rbegin()返回一个指向反转序列的第一个元素的迭代器
  • rend()返回反转序列的超尾迭代器。

7.2 deque

头文件

#include<deque>

deque模板类表示双端队列,支持随机访问,与vector的主要区别如下:

  • deque对象的开始位置插入和删除元素的时间都是固定的,但是vector中为线性时间。
  • 由于为了实现在deque两端执行插入和删除操作的时间为固定的这一目的,deque的对象设计比vector对象更为复杂,所以对于随机访问和在序列中执行插入和删除操作,vector容器执行这些操作时速度要快。

7.3 list

头文件

#include<list>

list模板类表示双向链表,与vector的区别:

  • list不支持数组表示法和随机访问,强调元素的快速插入和删除;vector强调通过随机访问进行快速访问
  • list从容器中插入或删除元素之后,链表迭代器指向元素将不变,在链表中插入新元素并不会移动已有的元素,而只是修改链接信息

在这里插入图片描述

7.4 forward_list(c++11)

forward_list:单链表,每个节点只链接下一个节点,所以只需要正向迭代器,是不可反转的容器。

7.5 queue

queue:适配器类,不允许随机访问队列元素,不允许遍历队列,可以将元素添加到队尾、从队首删除元素、查看队首和队尾的值,检查元素数目和测试队列是否为空。

在这里插入图片描述

7.6 priority_queue

priority_queue:适配器类,支持的操作与queue相同。

与queue的主要区别:

  • priority_queue中,最大的元素被移到队首
  • 默认的底层类是vector

7.7 stack

stack是适配器类,给底层类提供了典型的栈接口。``stack模板限制比vector`更多。不允许随机访问,不允许遍历栈,把使用限制在定义栈的基本操作上,可以将栈压入到栈顶,从栈顶弹出元素,查看栈顶的值,检查元素数目和测试栈顶是否为空。

在这里插入图片描述
7.8 array

头文件:

#include<array>

array没有定义调整容器大小的操作,定义了对它来说有意义的成员函数,operator[]()和at()

8.关联容器

8.1 关联容器

将值与键关联在一起,并使用键来查找值。提供对元素的快速访问,允许插入新元素,不能插入指定的位置。

关联容器通常用于确定数据放置位置的算法,以便可以快速检索信息。

关联容器是使用某种树实现的,树是一种数据结构,相对于链表,树的查找速度更快。

8.2 STL中提供的4种关联容器:set multiset map multimap

头文件:

#include<set.h>
#include<multiset.h>
#include<map.h>
#include<multimap.h>

8.2.1 四种关联容器

  • set :值类型与键相同,键是唯一的
  • multiset:可能有多个值的键是相同的
  • map:值与键的类型不同,键是唯一的,每个键只对应一个值
  • multimap:与map相似,一个键可以与多个值相关联

1、set是关联集合,可反转、可排序、且键是唯一的,所以不能存储多个相同的值,与vector和list类似,set使用模板参数来指定要存储的值类型。

/*
 * @Description: 
 * @version: 
 * @Author: sunshine
 * @Github: https://subshine.github.io/
 * @Email: 2182216077@ncepu.edu.cn
 * @Date: 2019-11-21 20:38:16
 * @LastEditTime: 2020-03-10 15:31:09
 */
// set example
#include <iostream>  
#include <string>
#include <set>
#include <algorithm>
#include <iterator>
using namespace std;
int main() {
    const int N = 6;
    string s1[N] = { "buf", "think", "for", "heavy", "can", "for" };
    string s2[N] = { "metal", "any", "food", "elegant", "deliver", "for" };
    set<string> A(s1, s1 + N);
    set<string> B(s2, s2 + N);
    ostream_iterator<string, char> out(cout, " ");
    cout << "Set A: ";
    copy(A.begin(), A.end(), out);
    cout << std::endl;
    cout << "Set B: ";
    copy(B.begin(), B.end(), out);
    cout << endl;
    //std::cout << A.keys() << std::endl;
    cout << "Union of A and B:\n";
    set_union(A.begin(), A.end(), B.begin(), B.end(), out);//并集
    cout << endl;
    cout << "Intersection of A and B:\n";
    set_intersection(A.begin(), A.end(), B.begin(), B.end(), out);//交集
    cout << std::endl;
    cout << "Difference of A and B:\n";
    set_difference(A.begin(), A.end(), B.begin(), B.end(), out);//获得两个集合的差
    cout << endl;
    set<string> C;    //python中set函数去重
    cout << "Set C:\n";
    set_union(A.begin(), A.end(), B.begin(), B.end(),
              insert_iterator<set<string> >(C, C.begin()));//合并起来按照顺序排列
    copy(C.begin(), C.end(), out);
    cout << endl;
    string s3("grungy");
    C.insert(s3);
    cout << "Set C after insertion:\n";
    copy(C.begin(), C.end(), out);
    cout << endl;
    cout << "Showing a range:\n";
    copy(C.lower_bound("ghost"), C.upper_bound("spook"), out);//截取字母g开头到字母s开头的部分
    cout << endl;
    return 0;
}

2、multimap

multimap是可反转的,经过排序的关联容器,但是键和值的类型不同,同一个键可能与多个值相关联。

为了将信息结合在一起,实际的值类型将键类型和数据类型结合为一对。STL使用模板类pair<class T,class U>将这两种值存储到一个对象中。

multimap<int,string> codes;
//创建multimap对象,键类型为int,存储的值类型为string

pair<const int,string> item(213,"Los Angeles");
codes.insert(item);

codes.insert(pair<const int,string>(213,"Los Angeles"));

//对于pair对象,可以使用first和second成员来访问其两个部分
cout<<item.first<<" "<<item.second<<std::endl;

//打印区号为718的所有城市
pair<multimap<KeyType,string>::iterator,multimap<KeyType,string>::iterator> range=codes.equal_range(718);
//也可以使用C++11自动类型推导功能

auto range=codes.equal_range(718);

cout<<"Cities with area code 718:\n";
std::multimap<KeyType,std::string>::iterator it;
for(it=range.first;it!=range.second;++it)
{
    cout<<(*it).second<<endl;
}
/*
 * @Description: 
 * @version: 
 * @Author: sunshine
 * @Github: https://subshine.github.io/
 * @Email: 2182216077@ncepu.edu.cn
 * @Date: 2019-11-21 20:38:16
 * @LastEditTime: 2020-03-11 10:56:52
 */
#include <algorithm>
#include <iostream>
#include <map>
#include <string>

typedef int KeyType;
typedef std::pair<const KeyType, std::string> Pair;
typedef std::multimap<KeyType, std::string> MapCode;

int main() {
     using namespace std;
     MapCode codes;
     codes.insert(Pair(415, "San Francisco"));
     codes.insert(Pair(510, "Oakland"));
     codes.insert(Pair(718, "Brooklyn"));
     codes.insert(Pair(718, "Staten Island"));
     codes.insert(Pair(415, "San Rafael"));
     codes.insert(Pair(510, "Berkeley"));

     cout << "Number of cities with area code 415: " << codes.count(415)
          << endl;

     cout << "Number of cities with area code 415: " << codes.count(718)
          << endl;
     cout << "Number of cities with area code 415: " << codes.count(510)
          << endl;
     cout << "Area Code City\n";
     MapCode::iterator it;
     for (it = codes.begin(); it != codes.end(); ++it) {
         cout << " " << (*it).first << " " << (*it).second << endl;
     }
     return 0;
}

在这里插入图片描述

9. 无序关联容器

无序关联容器:将值与键关联起来,使用键来查找值。

无序关联容器与关联容器的区别:

  • 关联容器是基于树结构的;
  • 无序关联容器是基于数据结构哈系表的,提高增加和删除元素的速度以及提高查找算法的效率

无序关联容器:

  • unordered_set
  • unordered_multiset
  • unordered_map
  • unordered_multimap

reference: C++primer第六版

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

纷繁中淡定

你的鼓励是我装逼的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值