STL
● STL:序列式容器—底层为线性结构的序列式容器
String类:专门存放字符的动态的顺序表
Array:存放任意类型的静态的顺序表 C++11 (了解)
Vector:存放任意类型的动态的顺序表(更看重于用数组来维护)
Forward_list:带头结点的循环单链表 C++11(单链表用的不多,了解接口即可)
List:存放任意类型的数据----带头结点的双向循环链表
Deque:动态的二维数组 (用的比较少)
● 特殊容器:
Stack:栈
Queue:队列
● 迭代器:方便用户便利的容器-------好处:可以不用知道容器底层的数据结构
C++:string::iterator-------------》char*
Vector::iterator--------》T*
String VS vector
1.array 定义的时候 必须定义数组的元素个数 ;而vector不需要;且只能包含整型字面值常量,枚举常量或者用常量表达式初始化的整型const对象,非const变量以及需要到运行阶段才知道其值的const变量都不能用来定义数组的维度。
2.array 定义后的空间 是固定的了,不能改变;而vector要灵活得多,可再加或减。
3.vector有一系列的 函数操作 ,非常方便使用; array 不提供push_back或者其他的操作在数组中添加新元素,array 一经定义就不允许添加新元素;若需要则要充许分配新的内存空间,再将原array 的元素赋值到新的内存空间。
4.array 和vector不同,一个数组不能用另一个数组 初始化 ,也不能将一个数组 赋值 给另一个数组;
Vector常见用法:
1.构造:空构造函数;n个值data元素的构造;区间构造;拷贝构造
2.容量操作:size(); capacity(); empty();
T():1.内置类型:0;2.自定义类型:调用无参的构造函数
Resize(newsize,data) :将vector中有效元素的个数更新到newsize
假设vector中有效元素的个数为oldsize
Newsize<=oldsize :不会缩小底层的空间大小,除非自己要减少空间
Newsize>oldsize:
Newsize<=capacity 增多的元素使用data来进行填充
Newsize>capacity 1.开辟空间 2.拷贝元素 3.释放旧空间
Reserve(newcapacity):为vector预留空间,注意:不会改变有效元素的个数
Newcapacity <= oldcapacity:返回
Newcapacity > oldcapacity:真正的进行扩容 SGI
3.元素访问
● T& operator[](size_t index) / const T& operator[](size_t index)con
● at(不太用)
● T& front() / const T& front()const
● T& back() / const T& back()const
operator[]和at的区别:越域时at只是抛异常;operator[]还给出错误提示。
4.元素修改的操作函数:
Assign:将区间(first,last)的元素赋值到当前的vector容器中,或者赋n个值为x的元素 到vector容器中,这个容器会清除掉vector容器中以前的内容。
v.assign(10,5);
swap:vector元素交换
clear:清除
emplace:empl=ace类似insert,emplace_back类似push_back。
5.迭代器:最主要是提供给算法来使用,让算法可以透明化(不用关心底层的数据结果)的操作数据
begin()/end()—>[begin,end) 正向迭代器 (左闭右开)
rbegin() / rend()—>[rbegin, rend) 反向迭代器
迭代器失效:
Vector中迭代器的类型:typedef T* iterator;
auto it = v.begin(); //it实际已经指向vector底层空间的起始位置
v.push_back(data);
再通过it迭代器访问vector中的元素--->可能会引起代码的崩溃
迭代器失效场景:
1.如果底层空间改变— push_back/insert resize/reserve swap/assign
2.erase(pos)—pos的迭代器失效 pos—>vector中某个对象—>T类型对象
解决迭代器失效:给迭代器重新赋值
it = v.erase(it);