底层原理:
vector是动态数组,内存地址中元素存储连续,内存不够时会自动扩容(x1.5/x2都有),必须先初始化才能索引。
~
定义一个迭代器:vector::iterator it;
迭代器是一种封装了指针功能的结构,可以理解为类似于智能指针。
~
初始化方式:
vector<type> v0(size,val): 放入size个val
vector<type> v0(v1): 拷贝构造
vector<type> v0(start,end):复制迭代器指向的[start,end)区间元素
子函数们:
push_back(): 尾插,O(1)
pop_back(): 尾删,O(1)
insert(a, x):a处插入x,O(n)
erase(pos): 删除pos位置元素,O(n)
clear(): 全删,O(n)
size(): 返回数量,O(1)
empty(): 判空,O(1)
resize(n): 重订大小为n,O(n)
begin(): 迭代器,指向首个元素
end(): 迭代器,指向末尾元素+1
reverse(start,end):反转迭代器指向的[start,end)区间元素
底层原理:
双端队列deque的底层也是个动态数组,但是和vector不一样,deque采用的是分段存储方式,因此不会有vector自动扩容再重新拷贝的问题。
~
初始化方式:
deque<int> dq; 空的
deque<int> dq1(5, 1); 初始5个1进去
deque<int> dq2(dq1); 拷贝构造
deque<int> dq3(start,end);迭代器指向区间构造,左闭右开
子函数们:
push_back(): 尾插,O(1);
push_front(): 头插,O(1);
pop_back(): 尾删,O(1);
pop_front(): 头删,O(1);
back(): 返回末尾元素,O(1);
front(): 返回头部元素,O(1);
size(): 返回元素的个数,O(1);
empty(): 判断是否为空,O(1);
clear(): 清空,O(n);
erase(pos): 删除pos位置的元素,O(n);
insert(n,"xxx"): 在n插入"xxx",O(n)。
底层原理:
底层是个字符数组,可以像数组一样操作,最爽的在于string可以直接用+来拼接
初始化方式:
string str2("123456789"); 生成"1234456789"的复制品
string str3("12345", 0, 3);结果为"123"
string str4("012345", 5); 结果为"01234"
string str5(5, '1'); 结果为"11111"
string str6(str2, 2); 结果为"3456789"
子函数们:
size()/length(): 长度,O(1)。
empty(): 判空,O(1)。
substr(pos,length): 从pos起,截取length长度的字符串,返回值是该串,O(n)
clear(): 清空,O(1)。
insert(n,"xxx"): 在n位置插入"xxx",O(n)
resize(n): 改变字符串的大小,O(n),其中n为字符串的大小。
replace(pos,length,"xxx") 在pos位置开始将length长度替换为"xxx",O(n)
find("xxx")/rfind(): 查找"xxx"首次出现的位置,O(n)
compare(str): 比较当前串与str的长度,可自定义,默认返回值大于则大于0,O(n)
底层原理:
双向链表list是由多个节点链接形成的,存储上不连续,节点包含自身的值和两个指针,指向前、后。
初始化方式:
list<int>lst(lst1);拷贝构造
list<int>lst(lst2.begin(),lst2.end());指定范围拷贝构造,左闭右开
子函数们:
push_front(val):头插,O(1)
push_back(val): 尾插,O(1)
pop_front(): 头删,O(1)
pop_back(): 尾删,O(1)
insert(pos,val):在迭代器pos位置插入val,O(1)
erase(pos): 删除迭代器pos指向的元素,O(1)
clear(): 全删,O(1)
size(): 个数,O(n)
empty(): 判空,O(1)
front(): 返回头部元素,O(1)
back(): 返回尾部元素,O(1)
sort(): 排序,默认从小到大,O(n)
sort可以自定义排序规则:
bool cmp(const string& s1, const string& s2) {
return s1>s2;
} 这就改成从大到小了
list.sort(cmp);
底层原理:
二者底层都是红黑树,数据有序,set数据不重复,multiset可重复,二者内部存储的都是数据,其与数组vector关联性非常强,用法也都类似,还可以直接拷贝vector,非常神奇。
初始化方式:
set<int> s2(s1); 拷贝构造
set<int> s(v.begin(), v.end());范围拷贝构造,左闭右开
子函数们:
insert() 插入元素,O(logN)。
emplace() 插入元素,O(logN)。
erase() 删除元素,O(logN)。
clear() 清空容器,O(N)。
find(key) 查找元素,O(logN)。
count(key) 统计元素个数,O(logN)。
empty() 判空,O(1)。
size() 返回总个数,O(1)。
begin(): 返回头的迭代器,O(1)。
end(): 返回尾+1,O(1)。
底层原理:
底层依旧是无敌的哈希表,由于哈希的特性,相比于vector,更适用于频繁插入删除的场景
构造方式和set一样,就不提了。
子函数们:
insert() 插入pair,O(1)
erase(key) 删除,O(1)
find(key) 查找,O(1)
operator[] 访问值,O(1)
size() 数量,O(1),因为有时刻维护size变量
empty() 判空,O(1)
底层原理:
二者底层都是红黑树,数据有序,map的key不重复,multimap可重复,二者内部存储的都是对组pair
multimap使用根据key值进行的一系列操作,会查到首个该key
子函数们:
insert() 插入元素,O(logN)。
emplace() 插入元素,O(logN)。
erase() 删除元素,O(logN)。
clear() 清空容器,O(N)。
find(key) 查找元素,O(logN)。
count(key) 统计元素个数,O(logN)。
empty() 判空,O(1)。
size() 返回总个数,O(1)。
begin(): 返回头的迭代器,O(1)。
end(): 返回尾+1,O(1)。
特别的:
operator[] 无脑索引,没索引到就插入一个,会爆内存
at(key) 有脑索引,没索引到就out_of_range异常
底层原理:
底层是无敌的哈希表,无序,但是key->value这个索引过程非常快,底层根据key通过哈希函数算出哈希值,直接索引。
子函数们:
insert() 插入pair,O(1)
erase(key) 删除,O(1)
find(key) 查找,O(1)
operator[] 访问值,O(1)
size() 数量,O(1),因为有时刻维护size变量
empty() 判空,O(1)
底层原理:
栈stack底层通过使用vector、deque或list等STL容器来实现,默认为deque,可使用stack
来指定底层容器
可用于实现单调栈法,解决找临近的首个大于/小于当前的值,是一种空间换时间的方法。
子函数们:
push(): 入栈,O(1)
pop(): 出栈,O(1)
top(): 返回栈顶元素的引用,可以直接对其进行赋值和修改,O(1)
empty():判空,O(1)
size(): 返回个数,O(1)
这里size为O(1)是因为stack时刻维护一个数量变量,size直接索引到它。
底层原理:
单向队列queue底层是双向队列deque,只提供单方向出队就变成了queue
子函数们:
push(): 入队,O(1)
pop(): 出队,O(1)
front():返回队头元素,O(1)
back(): 返回队尾元素,O(1)
size(): 个数,O(1)
empty():判空,O(1)