STL容器
Posted pedesis
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL容器相关的知识,希望对你有一定的参考价值。
iterator 迭代器
这就像是STL容器的指针,可以用星号"*"操作符解除引用
我们就先用vector举个例子
vector<int>::iterator it;//声明方式 it是迭代器名 //下面这两种遍历方式是等价的 for(int i=0;i<v.size();i++) cout<<v[i]<<endl; for(vector<int>::iterator it=v.begin();it!=v.end();it++) cout<<*it<<endl;
vector
头文件:<vector>
向量,个人习惯称为动态数组,因为它相当于一个不定长的数组,当数组长度达到目前最大长度的时候,会将数组的容量扩容至原来的两倍
初始化
1. vector<类型> 名称 //后面的容器都可以这样命名
2. vector<类型> 名称(最大容量)
3. vector<类型> 名称(最大容量,初始所有值)
4. vector<vector<类型> > 名称 //二维向量
v.size() 容器的实际长度 v.empty() 判断容器是否为空(bool) O(1)
由于STL容器基本都支持这些操作,所以后面不会再提及
v.push_back(x) 在数组末尾插入元素x v.pop_back() 在数组末尾删除一个元素
假设vector的实际长度为n,最大长度为m,当n=m时,会扩展一倍的容量,当n<=m/4时,会释放一半的空间,因此均摊后插入和删除的时间复杂度都近似O(1)(实际上vector的反复扩容在使用中是很耗时的)
v.clear() 清空容器(不会释放内存) O(n)
v.erase(iterator_x) 删除迭代器位置x上的元素
v.erase(iterator_x,iterator_y) 删除迭代器位置[x,y)上的元素 O(n)
调用该函数后,vector后面的元素会前移,所以在遍历时使用后通常会将迭代器自减
v.begin() 返回数组第一个元素的迭代器 O(1)
v.end() 返回数组最后一个元素后的迭代器 O(1)
所有的容器都可以视为一个前闭后开的结构,因此end函数返回的是vector尾部的边界,该位置无元素
v.front() 返回数组的第一个元素 v.back() 返回数组的最后一个元素 O(1)
前者等价于 *v.begin() 和 v[0],后者等价于 *--v.end() 和 v[v.size()-1]
v.reserve(x) 增加容量到大于或等于x的值 若x小于实际长度则无意义 O(n)
v.swap(vector_x) 与另一个同类型vector交换数据 O(1)
v1=v2 两个vector之间可直接用"="号赋值 O(n)
stack
头文件:<stack>
栈,按照先进后出的原则存储数据,没什么特殊的函数,手写十分方便,跑得也更快,所以这个容器就不多讲了
queue
头文件:<queue>
队列,按照先进先出的原则存储数据
q.push(x) 在队尾插入元素 O(1)
q.pop() 删除队首元素 O(1)
q.front() 返回队首元素 O(1)
q.back() 返回队尾元素 O(1)
priority_queue
头文件:<queue>
优先队列,相当于一个大根二叉堆(但不支持删除堆中任意元素),每次取出优先级最高的元素
pq.push(x) 在堆中插入元素 O(log n)
pq.pop() 删除堆顶元素 O(log n)
pq.top() 返回堆顶元素 O(1)
实现小根堆
priority_queue<int,vector<int>,greater<int> > pq; //或重载运算符 struct Data{ int num; bool operator< (Data rhs) const{ return num>rhs.num; } }; priority_queue<Data> pq;
deque
头文件:<deque>
双向队列,支持在两端高效插入或删除元素,与vector相比,它在头部增删元素仅需要O(1)的时间,与queue相比,它像数组一样支持随机访问
[] 访问元素 O(1)
dq.push_back(x) 从队尾入队 O(1)
dq.push_front(x) 从队头入队 O(1)
dq.pop_front() 从队头出队 O(1)
dq.pop_back() 从队尾出队 O(1)
dq.begin()/end() 返回队头/队尾迭代器 O(1)
dq.front()/back() 返回队头/队尾元素 O(1)
list
头文件:<list>
双向链表,将元素储存在链表中,允许快速的插入和删除,但是随机访问却比较慢,所以它经常用于内部任意位置(即除了头尾以外的其他位置)元素的频繁增删
l.insert(iterator_p,x) 在p位置插入一个x元素 O(1)
l.insert(iterator_p,n,x) 在p位置插入n个x元素 O(n)
这里的O(n)指n的大小,同理后面有关区间的操作,O(n)是指区间长度
l.insert(iterator_p,iterator_x,iterator_y) 在p位置插入[x,y)中的元素 O(n)
l.push_back(x) 在链表尾部插入元素x O(1)
l.push_front(x) 在链表开头插入元素x O(1)
l.pop_back() 删除链表尾部元素 O(1)
l.pop_front() 删除链表开头元素 O(1)
l.begin()/end() 返回首尾迭代器 O(1)
l.front()/back() 返回首尾元素 O(1)
l.clear() 清空 O(n)
l.erase(iterator_x) 删除位置x的元素 O(1)
l.erase(iterator_x,iterator_y) 删除位置[x,y)的元素 O(n)
l.remove(x) 删除所有与x匹配的元素 O(n)
l.swap(list_x) 与另一个list交换数据 O(1)
l.merge(list_x) 将升序链表l与x归并为升序链表l,链表x变为空 O(n)
l.reverse() 将链表翻转 O(n)
l.unique() 除去链表中的重复元素(除第一个) O(n)
l.sort() 以升序将链表排序 O(n log n)
set
头文件:<set>
有序集合,内部元素保持有序(默认从小到大)且不重复(multiset可以包含重复元素)
s.insert(x) 向集合中插入元素 O(log n)
s.clear() 清空 O(n)
s.erase(x) 删除元素x O(log n)
s.erase(iterator_x) 删除迭代器指向的元素 O(log n)
s.begin()/end() 返回集合首尾迭代器 O(1)
s.find(x) 返回元素x的迭代器 若不存在返回s.end() O(log n)
s.lower_bound(x) 返回大于等于x的最小元素的迭代器 O(log n)
s.upper_bound(x) 返回大于x的最小元素的迭代器 O(log n)
s.count(x) 返回元素x的个数 O(log n)
map
头文件:<map>
映射,表示键(key)到值(value)的映射,key保持有序(默认从小到大),这个容器强的地方在于支持很多数据类型之间的映射,甚至字符串和结构体
初始化 map<key,value> m;
[] 插入值和获取值 O(log n)
m.clear() 清空 O(n)
m.erase(x) 删除key为x的元素 O(log n)
m.erase(iterator_x) 删除迭代器指向的元素 O(log n)
m.begin()/end() 返回首尾迭代器 O(1)
m.find(x) 返回key为x的元素的迭代器 若不存在返回m.end() O(log n)
m.count(x) 返回key为x的元素个数(非0即1) O(log n)
以上是关于STL容器的主要内容,如果未能解决你的问题,请参考以下文章