C++ STL 标准模板库
一、标准容器
vector 向量容器
deque 双端链表容器
list 链表容器
二、容器适配器
底层通过标准容器实现,但是对外部提供不同功能的接口
stack 栈
queue 队列
priority_queue 优先队列
三、关联容器
无序关联容器 链式哈希表o(1)
unordered_set 无序单重集合
unordered_multiset 无序多重集合
unordered_map 无序的单重映射表
unordered_multimap 无序分多重映射表
有序关联容器 红黑树o(log2n)
set 单重集合
multiset 多重集合
map 单重映射表
multimap 多重映射表
四、近容器
数组 string bitset
五、迭代器
iterator和const_iterator 普通迭代器和常量迭代器
reverse_iterator和const_reverse_iterator 正向迭代器和反向迭代器
六、函数对象
greater和less
七、泛型算法
针对数据的其他操作
sort find find_if binary_search for_each
vector向量容器
底层数据结构,动态开辟数组,每次以原来空间大小二倍扩容
vectorvec;(优点,尾插、尾删、访问)
vec.push__back(20);末尾添加元素O(1) 可能导致容器扩容
allocate:allocate开辟空间\deallocate释放空间\construct构造\destroy析构
vec.insert(it,20); it迭代器指向的位置添加一个元素20 O(n)
vec.pop();末尾删除元素 O(1)
vec.erase(it);删除it迭代器指向的元素
vec.erase(迭代器区间)
operator[]:下标的随机访问vec[5] O(1)
iterator迭代器遍历
注意:对容器进行连续插入或者删除操作(insert/erase),一定要更新的迭代器,否则第一次insert/earse完成,迭代器就失效了
常用方法:
size()
empty()
reserve(20) vector预留空间,开辟空间不添加元素
resize(20) vector扩容,开辟空间,添加元素
swap 交换元素
vecotr特点:动态数组内存连续,2倍方式进行扩容
int main()
{
vector<int>vec;
vector<int>vec1(10);//初始化10个整形空间
vector<int>vec2(10, 20);//初始化10个整形空间,所有控件初始化值为20
//也可以传入一个迭代器区间,把迭代器区间的元素放到容器中
int arr[] = { 12,23,45,56,78,89 };
int len = sizeof(arr) / sizeof(arr[0]);
vector<int>vec3(arr, arr + len);//指针就是数组的迭代器
for (int i = 0;i < 20;++i)
{
vec.push_back(i);
}
for(int k:vec)
{
cout << k << endl;
}
for(int i = 0;i<vec.size();i++)
{
cout << vec[i] <<endl;
}
auto it = vec.begin();
vector<int>::iterator it2 = find(vec.begin(),vec.end(),15);
for (; it != vec.end();it++)
{
cout << *it << endl;
}
return 0;
}
reserve和resize这两个函数一定要区分清楚
int main()
{
vector<int>vec;
vec.reserve(20);
cout << vec.size() << endl;
vec.resize(20);
cout << vec.size() << endl;
return 0;
}
deque和list容器方法同上类似,不过增加了头部和尾部的快速删除
c.front() ; //返回第一个元素,不检查元素是否存在
c.back(); //返回最后一个元素
c.push_front()
c.push_back()
c.pop_front()
c.pop_back()
vector和deque之间的区别?
1、底层数据结构 vector是动态开辟的数组,deque 底层是双端队列(二维数组)
2、前中后插入元素的时间复杂成都 后中O(1) 前 dequeO(1) vectorO(n)
3、内存使用效率 vectoe必须连续存储,deque可以不容连续
4、在中间进行insert或者erase,vector效率更好 deque由于底层内存不连续,效果差一点
5、deque支持头部尾部快速插入删除,快速按位访问
vector和list之间的区别?
1、底层数据结构,一个是动态数组,一个是双向循环链表
2、增删改查的时间复杂程度 数组:增加删除 o(n) 查询o(n) 随机访问o(1) 链表:增加删除o(1)
容器适配器
怎么理解容器适配器?
1、适配器底层没有自己的数据结构,是另外一个容器的封装,他的方法,全部由底层以来的容器进行实现的
2、没有自己的迭代器
stack: push入栈 pop出栈 top查看栈顶元素 empty判断栈空 size返回元素个数
queue:push入队 pop出队 front查看队头元素 back查看队尾元素 empty判断队空 size返回元素个数
deque和stack为什么不依赖于vector
1、vector的初始内存使用效率太低了,deque初始化开辟1024个数组空间
2、对于queue,需要支持尾入头出,O(1),如果依赖vecotr其底层出队效率很低
3、vector需要大片的连续内存,而deque只需要分段的内存,当存储大量数据时,显然deque对于内存的利用率更好一些
priority_queue:push入队 pop出队 top查看队顶元素 empty判断队空 size返回元素个数
priority__queue底层依赖vector:
底层默认吧数据组成一个大根堆结构,在内存连续的数组上构建大根堆和小根堆
int main()
{
vector<int>vec;
deque<int>deq;
list<int>list;
for (int i = 0;i < 20;i++)
{
vec.push_back(rand() % 100);
deq.push_back(rand() % 100);
list.push_back(rand() % 100);
}
cout << vec.size() << endl;
cout << deq.size() << endl;
cout << list.size() << endl;
auto it1 = vec.begin();
auto it2 = deq.begin();
auto it3 = list.begin();
for (int i = 0;i < vec.size();i++)
{
cout << *it1 <<" ";
it1++;
}
cout << endl;
for (int i = 0;i < vec.size();i++)
{
cout << *it2 << " ";
it2++;
}
cout << endl;
for (int i = 0;i < vec.size();i++)
{
cout << *it3 << " ";
it3++;
}
cout << endl;
return 0;
}