C++ vector、list用法总结

常用容器之二—— vector 和 list 。

目录

vector(向量):

优点

缺点

 resize() 和 reserve() 的区别

1. resize(n)函数:

2. reserve(n)函数:

区别:

初始化

访问

 赋值

插入

删除

清空

收缩内存

list(双向链表):

优点

缺点

初始化

基本函数

赋值

合并

删除 

倒转(逆序)

排序

交换 

删除重复元素


vector(向量)

vector是一个能够存放任意类型的动态数组,只能在尾部进行插入和删除,其实它的用法和数组一样,只是它的功能比数组强大。

优点

           1.可以随机访问任意一个元素。(和数组一样)

           2.它是动态数组,动态数组是当内存不够的时候,它可以自动扩增,而不需要我们人为地进行扩增。

缺点

          和数组一样,不能很好的进行插入和删除操作。

必须加头文件 #include<vector>

先简单介绍一下函数 push()、empty()、pop()、size()、capacity()、max_size()。

push_back();  //在向量尾部增加一个元素 

empty();  //判断向量是否为空

pop_back();  //删除向量中最后一个元素

size();  //返回向量中元素的个数

resize();  //设置大小(调整容器的长度)

capacity();  //返回当前向量的容量

max_size();  //返回可允许的元素数量的最大值

其实这些函数的用法与之前我们所学的string和stack、queue里面的用法是一样的 ,特别是capacity()和resize()函数。

具体请参照之前 string 的博客。
 

reserve();  //设置容量(调整容器的容量大小)

在这里主要区分一下 resize() 和 reserve() 函数。

1. resize(n)函数

                           resize(n):调整容器的长度大小,使其能容纳n个元素

                                             如果n小于当前的size,则删除多出来的元素,反之,不够的用值初始化元素的默认值来填充。

                           resize(n,t):这是对于n大于当前的size的情况时,就将新增加的元素都初始化为t(即用t来填充)。

2. reserve(n)函数

                           reserve(n):预分配n个元素的存储空间。

                                               如果n小于或者等于capacity,其容量就不会变,反之,就重新分配内存空间,从而使capacity=n。

简单点说,就是 resize()函数与容器的size有关,而reserve()函数与容器的capacity有关

区别

调用resize()函数后,所有的空间都已经初始化了,所以可以直接访问;而reserve()函数预分配出的空间没有被初始化,所以不可访问。

可以看到,最开始增加元素数量为10时,而此时容量16比10大,这是因为计算机认为你可能还要再增加元素,所以就多开辟了一些空间。 

另外还有一些函数,front()、back()。

front();  //返回首元素

back();  //返回尾元素

以上函数就不再细说了,在下面的代码中都会经常用到。 

初始化

//Vector<类型>标识符

vector<int>v;  //创建一个空的 vector

 

//Vector<类型>标识符(最大容量)

vector(int n);  //创建一个元素个数为 n 的vector

以上两种最好还是用第二种形式。

原因:

 

 可以看到,随着元素个数的增加,容量也由0变为了1,而我们前面学string的时候就学习过容量capacity()函数的特性,当元素个数超过了容量之后,此时我们就需要创建一个更大容量的数组,然后把数据复制到这个新数组中,这样会大大降低效率,所以我们尽量不这样做,相比之下,所以我们还是尽量采取以下形式:(提前为其分配空间 )

//Vector<类型>标识符(最大容量,初始值)

vector(int n,const t)  //创建一个 vector,元素个数为n,且值均为t

//Vector<类型>标识符(begin,begin+n) 

vector<类型>v1();  //先构造容器v1

vector<类型>v(v1.begin(),v1.begin()+n);  //用v1将v初始化

这样也可以:

用数组对容器进行初始化

总之是可以这样用的,至于其中的道理,我是这样来理解记忆的(虽然不一定理解对了,但最起码能帮助记住):

 

 以上就是初始化的方法。

访问

直接使用中括号来访问  //与数组用法一样

对了,要是想让它们都输出在第一行,就这样写就好了:

 at();

区别:中括号与at()函数的区别就在于at()能检测是否越界,具体的我们在学string时都有详细了解过,如果还不明白的话可以去看一下之前的string的博客。

 赋值

插入

insert();

删除

 erase();

清空

 clear();

收缩内存

swap();

 

可以看到,当我们使用swap来收缩内存的时候,其容量也确实随之变了。

list(双向链表)

优点

1. 与向量(vector)相比,它可以快速的进行插入和删除操作。

2. 不使用连续的内存空间就可以随意的进行动态操作。

缺点

1. 由于它是链表,所以它随机访问比较慢,相比vector不能使用at()来访问

2. 相对于 vector 占用了更多的内存。

必须加头文件 #include<list>

初始化

它的初始化与向量(vector)的初始化方法基本上是一样的(也是上面那5种方法)。

基本函数

它的基本函数与上面向量(vector)的大同小异,可以参照上面的。

还有函数:

begin();  //返回指向第一个元素的迭(die)代器

end();  //返回末尾的迭(die)代器

下面来列举一下不同于以上的函数:

赋值

list assign();  //给list赋值

也可以这样:

当然链表list同以上vector一样也可以直接将一个链表赋值给另一个链表,如下:

合并

merge();

删除 

remove();

倒转(逆序)

reverse();  //将链表list中的元素倒转 

 

排序

sort(); 

交换 

swap();

删除重复元素

unique(); //删除list中重复的元素

以上是两个比较常用的容器vector和list的相关函数以及用法的总结,其实可以把它们两个看成正好相反的两个,也是比较有意思的哈哈。
发布了23 篇原创文章 · 获赞 30 · 访问量 8680

猜你喜欢

转载自blog.csdn.net/l218623/article/details/104134910