容器总结

概念

容器是什么

容器定义:
在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对象的指针,这种对象类型就叫做容器。
定义简单理解:
容器这种对象类型,从单词表面意思理解就是包含,包含了什么呢,是我们需要的存储结构的对象,这样的对象集成了特定存储结构和对存储的操作方式,可以重复利用这些代码方便编程。
在C++中的容器:
因为C++ 中处理容器是采用基于模板的方式,在C++ 中,标准模板库(STL )中包含了容器。STL中的容器提供了多种数据结构,例如栈,队列,数组等等。这些内容大家一定很熟悉。

通用容器的分类

STL 对定义的通用容器分三类:顺序性容器、关联式容器和容器适配器。

顺序性容器

顺序性容器是一种各元素之间有顺序关系的线性表。顺序性体现在哪里呢,这种顺序不依赖于元素的值,而是与元素加入容器的位置相对应。比如我们一次在某个位置加几个元素,这些元素就会按我们的操作顺序出现在那里。

关联式容器

关联式容器和顺序性容器不一样,关联式容器是非线性的树结构,更准确的说是二叉树结构。各元素之间没有严格的物理上的顺序关系,不像顺序性容器中例如队列、栈那样有着操作逻辑的顺序体现。尤其是地址上,它也不是顺序性的。虽然在关联式容器的操作中可以貌似“顺序地”获取元素,但是其实是借助的关联特点实现的。

关联式容器另一个显著的特点是它是以键值的方式来保存数据,就是说它能把关键字和值关联起来保存,而顺序性容器只能保存一种(可以认为它只保存关键字,也可以认为它只保存值。

容器适配器

容器适配器在C++的解释是:适配器是使一事物的行为类似于另一事物的行为的一种机制。它本身不能直接保存元素,它保存元素的机制是调用另一种顺序容器去实现,可以通俗理解成为现有的容器做接口。
STL 中提供的三种适配器可以由某一种顺序容器去实现。默认下stack 和queue 基于deque 容器实现,priority_queue 则基于vector 容器实现。可以自己指定顺序容器,但是要注意一个适配器不是可以由任何一个顺序容器来实现的。

容器的具体分类

按照上面的概念,我们对介绍过的容器进行性质分类,

顺序性容器:

  1. vector,相当于动态数组,可自动扩展
  2. deque,双端队列
  3. list,双向链表

关联式容器:

  1. set/multiset, 集合,多重集合
  2. map/multimap,键-值

容器适配器:

  1. stack,栈
  2. queue,队列
  3. priority_queue,优先级队列

函数速记

学习完这么多容器,可以明显感觉出这些容器的操作方法上有非常高的重复性,于是整理了下面的内容来对比速记。

1. 构造

对于顺序性容器,vector,deque,list来说,下面的方法通用

容器本身名字<数据类型> 定义的容器名; //无参构造
容器本身名字<数据类型> 定义的容器名1(定义的容器名2.begin(), 定义的容器名2.end()); //区间拷贝
容器本身名字<数据类型> 定义的容器名(10, 100);  //指定元素个数的拷贝
容器本身名字<数据类型> 定义的容器名1(定义的容器名2);  // 拷贝构造函数
//举例
vector<int> v1; //无参构造
vector<int> v2(v1.begin(), v1.end()); //区间拷贝
vector<int> v3(10, 100);  //指定元素个数的拷贝
vector<int> v4(v3);  // 拷贝构造函数

对于关联式容器和容器适配器,常用下两种

容器本身名字<数据类型> 定义的容器名; //无参构造
容器本身名字<数据类型> 定义的容器名1(定义的容器名2);  // 拷贝构造函数
//举例
vector<int> v1; //无参构造
vector<int> v4(v3);  // 拷贝构造函数
2. 赋值

对于顺序性容器,vector,deque,list来说,下面的方法通用

定义的容器名1 = 定义的容器名2; //重载运算符
assign(定义的容器名2.begin(), 定义的容器名2.end()); //区间赋值
assign(元素个数,元素);  //指定元素个数的拷贝赋值
//举例
v2 = v1;
v3.assign(v1.begin(), v1.end());
v4.assign(10, 100);

对于关联式容器和容器适配器,就直接“=”

定义的容器名1 = 定义的容器名2; //重载运算符
//举例
v2 = v1;
3. 大小相关
通用接口
empty();               //判断容器是否为空
size();               //返回容器中元素的个数
顺序和关联有的
swap(st);      //交换两个集合容器
顺序有的
resize(int num);      //重新指定容器的长度为num
resize(int num,elem);      //重新指定容器的长度为num,指定填充默认值
4. 插入删除

顺序式的区分,

vector,deque,list共有的
//尾插
v1.push_back(10);
//尾删
v1.pop_back();
//插入
v1.insert(v1.begin(), 100);  // 插1个100
v1.insert(v1.begin(), 2, 1000); // 插2个1000
//删除
v1.erase(v1.begin());
//清空
v1.erase(v1.begin(), v1.end());
v1.clear();
deque,list才有的双端操作
//头插
L.push_front(100);
//头删
L.pop_front();
list有的
L.remove(10000);  //删除匹配值

关联式的共性不大,暂时没有整理
容器适配器共有,但是存取的位置要结合特性,
栈是先进先出,栈顶添加栈顶移除
队列是先进后出,尾添加首移除

q.push(p1);
q.pop();
5. 存取相关

对于顺序式容器来讲,返回值

vector,deque和list通用,
q.front();  //返回容器中第一个数据元素
q.back();  //返回容器中最后一个数据元素
vector和deque有的,索引返回值
v1[i];
v1.at(i);

对于关联式容器来讲,查找统计通用

m.find(key);
m.count(key);

对于容器适配器来讲,区分非常好记

//栈只会返回top值
s.top(); //栈返回top值
// 队列会返回首尾值
q.front(); // 队列返回首值
q.back(); // 队列返回尾值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值