vector数据结构和数组非常相似,也称为单端数组。
vector与普通数组的区别:数组是静态空间,而vector可以动态拓展。
数组静态空间:数组在声明时即指定了大小。无法再改变。vector动态拓展:并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝到新空间中,释放原空间。动态拓展机制:类似于C#种的ArrayList的Capacity拓展,当空间不足时,自动开辟。ArrayList会自动翻倍,但是vector不会翻倍,他会增加当前容量的一半。
vector
输出:
v1初始化的容量:0v1加入0之后的容量为:1v1加入1之后的容量为:2v1加入2之后的容量为:3v1加入3之后的容量为:4v1加入4之后的容量为:6v1加入5之后的容量为:6v1加入6之后的容量为:9v1加入7之后的容量为:9v1加入8之后的容量为:9v1加入9之后的容量为:13v1加入10之后的容量为:13v1加入11之后的容量为:13v1加入12之后的容量为:13v1加入13之后的容量为:19v1加入14之后的容量为:19v1加入15之后的容量为:19v1加入16之后的容量为:19v1加入17之后的容量为:19v1加入18之后的容量为:19v1加入19之后的容量为:28v1加入20之后的容量为:28v1加入21之后的容量为:28v1加入22之后的容量为:28v1加入23之后的容量为:28v1加入24之后的容量为:28v1加入25之后的容量为:28v1加入26之后的容量为:28v1加入27之后的容量为:28v1加入28之后的容量为:42v1加入29之后的容量为:42
容量扩增为当前容量的一半,1,2, 3,4, 6, 9, 13, 19, 28, 42。每次增加的都是前一刻的一半。
vector通常,前端封闭,不允许前端插入,只允许尾插和尾删法。push_back()和pop_back()。front()代表容器中的第一个元素。back()是容器中最后一个元素。vector中有几个迭代器:
常用的是v.begin():代表的是容器中的第一个元素的位置(迭代器指向第一个元素)。v.end():指向容器中最后一个元素的下一个位置。v.rbegin():指向容器中的最后一个元素,也就是从右边数第一个元素。v.rend():指向第一个元素的前一个位置。从右侧数最后一个,即第一个。还有其他接口,比如:插入insert()以及删除erase()等。vector容器的迭代器是支持随机访问的迭代器。最强悍的迭代器:跳跃式访问。
vector构造函数
函数原型:
vector 注意第二个通过区间的方式构造,最后一个v.end(),如上图中所示,最后一个位置是取不到的。所以前闭后开,包头不包尾巴。 4种构造方法如下: // 为了方便:我们写一个通用的打印vector void test01(){// 1、默认构造:无参构造vector 函数原型: vector& operator=(const vector &vec);//重载等号操作符 assign(v.begin(), v.end()); //将[begin, end)区间(也是前闭后开)中的数据拷贝赋值给本身。 assign(n, elem); //将n个elem拷贝赋值给本身。 也是两种方法: 一种是重载等号=操作符;一种是采用成员函数assign的方式。 void test02(){// 声明+初始化;vector 函数原型: empty(); //判断容器是否为空capacity(); //容器的容量size(); //返回容器中元素的个数resize(int num); //重新指定容器的长度为num, 若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。resize(int num, elem); //重新指定容器的长度为num, 若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除 函数原型: push_back(ele); //尾部插入元素elepop_back(); //删除最后一个元素insert(const_iterator pos, ele); //迭代器指向位置pos插入元素eleinsert(const_iterator pos, int count,ele);//迭代器指向位置pos插入count个元素eleerase(const_iterator pos); //删除迭代器指向的元素erase(const_iterator start, const_iterator end);//删除迭代器从start到end之间的元素clear(); //删除容器中所有元素 void test01(){vector 注意:insert和erase要传入的参数是迭代器。 小结: 尾插 --- push_back 尾删 --- pop_back 插入 --- insert (位置迭代器) 删除 --- erase (位置迭代器) 清空 --- clear 函数原型: at(int idx); //返回索引idx所指的数据 :类似string容器。成员函数at。 operator[]; //返回索引 [idx] 所指的数据:类似string容器。 front(); //返回容器中第一个数据元素 back(); //返回容器中最后一个数据元素 函数原型: swap(vec); // 将vec与本身的元素互换。实现两个容器元素互换。 void printVector(int val){cout << val << " ";}void test01(){vector 输出: 交换前v1:0 1 2 3 4 5 6 7 8 9交换前v2:10 9 8 7 6 5 4 3 2 1交换后:交换后v1:10 9 8 7 6 5 4 3 2 1交换前v2:0 1 2 3 4 5 6 7 8 9 // 实际用途:巧用swap可以收缩内存空间。void test02(){vector 解析: vector 这行代码中,有两个部分组成: 第一部分:vector 匿名对象,依据当前v占用3个元素,匿名对象也占据3个元素,容量也为3,这样与v进行交换之后,实现了对v的内存压缩。 匿名对象执行完之后。立马由编译器回收。用完即删。不用担心占用内存。 总结:swap可以使两个容器互换,可以达到实用的收缩内存效果。 功能描述: 减少vector在动态扩展容量时的扩展次数 函数原型: reserve(int len);//容器预留len个元素长度,预留位置不初始化,元素不可访问。 分配了内存,但是这块内存没有初始化,所以不可访问。 void test01(){vector 动态拓展容量的次数 num = 30 十万数据,vector容量动态拓展30次,每一次拓展,都要把原来的数据重新开辟空间,然后将数据拷贝过去,然后把原空间释放。这样是对资源和效率的浪费。 所以有了预留空间。 假设我们需要预留的空间很大,而且可以预估我们需要的空间。那我们可以采用预留空间的方式,来提高效率。 void test01(){vector 动态拓展容量的次数 num = 1
vector赋值操作
vector容量和大小
vector容器插入和删除
vector元素存取
vector容器互换元素
1、容器互换:
vector预留空间