C++ Primer------------------------顺序容器

容器:一些特定类型对象的集合
顺序容器:为程序员提供控制元素存储方式一定顺序访问元素的能力。
标准容器如下(标准库):快速顺序访问元素的能力

	 - vector	:可变大小数组    连续空间存储,所以在两端添删元素快速,中间添删很慢。
	 - deque:双端队列	连续空间存储,所以在两端添删元素快速,中间添删很慢。
	 - forward_list :单向链表 非连续空间存储,但只能在尾部添删元素。
	 - list	:双向链表。 非连续空间存储,都很快,但是浪费空间
	 - array:固定大小数组。连续空间存储,不能增删、扩张大小。
	 - string:于vectpr类似,但专门保存字符。   连续空间存储,所以在两端添删元素快速,中间添删很慢。

增删元素速度:

 - vector:连续空间存储,所以在两端添删元素快速,中间添删很慢。
 - deque:连续空间存储,所以在两端添删元素快速,中间添删很慢。
 - forward_list: 非连续空间存储,但只能在尾部添删元素。
 - list:非连续空间存储,都很快,但是浪费空间。
 - array:连续空间存储,不能增删、扩张大小。
 - string	:连续空间存储,所以在尾部添删元素快速,中间添删很慢。

遍历速度:

 - vector	:可用下标形式或者迭代器遍历,速度很快
 - deque:速度很快
 - forward_list :遍历较慢,不支持元素随机访问,因为只能从头开始遍历,查找某元素,较慢
- list	:遍历较慢,不支持元素随机访问,因为只能从头开始遍历,查找某元素,较慢
 - array:连续空间存储,可通过下标或迭代器遍历,速度很快。
 - string:可用下标形式或者迭代器遍历,速度很快。

注意:
1. 使用vector是更好的选择,除非又理由选择其他容器
2.尽量使用迭代器,不能使用下标操作,避免随机访问,防止越界。

选择条件:

  1. 若要求可随机访问元素,则应用vectordeque
  2. 若要求在容器中间插入或删除元素,则选择listforward_list
  3. 若在两头插入或删除元素,不会在中间位置插入或删除,则使用deque

迭代器

迭代器范围:由一对迭代器表示,分贝指向同一个容器的元素或尾元素的后一个位置(begin、end或first、last)。
左闭合区间:因为end、last表示最后一个元素的后一个位置,所以[bgein,end)。
使用左闭合范围的假定:

  1. 如果begin和end相等,则范围为空
  2. 若begin和end不等,则范围至少包含一个元素,begin指向第一个元素
  3. 可对begin递增,使得begin=end
while(begin!=end)
	*begin=v  //范围不空,则begin解引用进行赋值
	++begin    //移动迭代器,指向下一个元素

C++11 auto自动判断类型

list<string> a={"a","ab","abc"};
auto it1=a.begin();            //  list<string>:iterator
auto it2=a.rbegin();			//  list<string>::reverse_iterator
auto it3=a.cbegin();		//  list<string>::const_iterator
auto it4=crbegin();			//  list<string>::const_reverse_iterator

容器定义和初始化

每个容器类型都定义了一个默认构造函数,除了array之外,其他容器默认构造函数都会创建一个指定类型的空容器,且都可以接受指定容器大小和元素初始值的参数。

C S  //默认构造函数,若C为array,则元素按默认方式初始化,否则C为空。
C c1(c2); //c1初始化为c2的拷贝,c1和c2必须是相同类型的容器,且保存相同类型的元素。
C c{a,b,c...}  //c初始化列表中元素的拷贝。
C c={a,b,c...};
C c(b,e);  //c初始化为迭代器b和e指定范围的元素的拷贝。元素类型必须相同。
只有顺序容器(不包括array)的构造函数才能接受大小参数
C s(n);   //包含n个元素,这些元素进行了值初始化,构造函数是explicit的
C s(n,t);   //s包含值为t的n个元素

将一个容器初始化为另一个容器的拷贝

方法1:直接拷贝容器。(容器类型必须相同,元素类型必须相同)

list <string>s1;
slit<string> s2(s1);

方法2:拷贝由迭代器指定的元素范围(array除外),(容器类型不必相同,元素类型也可以不同)

list <string>s1;
slit<string> s2(s1.begin(),s1.end());

array的初始化和赋值

定义array时,不仅需要指定元素类型,还需要指定大小

array<int,10>  c//保存10个int类型的数组
array<int,10>::size_type s=c.size();  //保存c的大小
  1. 初始化:
array<int,10> c;  //默认初始化
array<int,10>  c1{1,2,3,3};  //列表初始化
array<int,10>  c2={1,2,3,3};  //列表初始化
array<int,10>  c3=c;  // 拷贝array数组类型

注意:虽然不能对内置数组类型进行拷贝,但是array可以。
2. 赋值
array允许赋值,但是=号两面运算对象必须具有相同类型。

array<.int,10> c1;
array<int,10> c2;
c2=c1;  //正确,两边都是array,元素都是int
c2={0};  //错误,不能用花括号赋值,只能定义 

删除元素

  1. erase:从容器中指定位置删除元素。可以删除由一个迭代器指定的单个元素或一对迭代器指定范围的所有元素。
    返回值:返回指向删除的最后一个元素之后位置的迭代器。
list<int> lst={1,2,3,4,5,6,7,8,3};
auto it=lst.begin();   //it类型为list<int>::iterator,指向第一个元素的迭代器
while(it!=lst.end())   
{
	if(*it%2)
	it=lst.erase(it);//若该元素为奇数,则删除
	else
	++it;
}

删除多个元素,通过一对迭代器。

ele1=slt.erase(ele1,ele2);  //返回指向最后一个被删除元素之后位置的迭代器,执行后ele1==ele2。

删除所有元素clearerase,不适用于array

slt.clear();
slt.erase(slt.begin(),slt.end());

改变容器大小resize, 不适用于array

list<int> lst(10,20);  //10个int,每个值都是20.
lst.resize(15);  //将5个值为0的值添加到末尾
lst.resize(10,20);  //将10个值为20的元素添加到尾部
lst.resize(5);   //只保存5个元素,最前面五个

标准库爱采用了可以减少容器空间分配次数的策略,当不得不获取新的内存空间时,通常分配更大的内存空间。
管理容器的成员函数

//只适用于vector和string
c.capacity();  //不重新分配内存空间,c可以保存多少元素
c.reserve(); //分配至少能容纳n个元素的内存空间

shrink_to_fit只适用于vectorstringdeque
新标准中,我们调用shrink_to_fit退回不需要的内存空间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值