STL学习笔记
Vector
void VectorTest()
{
vector<int> vect;
vect.push_back(1);
vect.push_back(20);
vect.push_back(12);
vect.push_back(12);
vect.push_back(12);
sort(vect.begin(),vect.end());
for(vector<int>::iterator iter=vect.begin();iter!=vect.end();++iter)
{
cout<<*iter<<endl;
}
cout<<vect.size()<<endl;
cout<<vect.capacity()<<endl;
//直接用索引和at的区别:
//vect[x]不会检查索引的范围,超出时返回默认值
//vect.at(x)会检查索引的范围,当索引超出时会报错
cout<<vect[-1]<<endl;
// cout<<vect.at(10)<<endl;
}
vector is a dynamically allocated contiguous array in memory
Sequence containers
- vector
- deque
- list
- forward list
- array
Associative Containers
- set,multiset
- map,multimap
Unordered Containers(hash table)
- Unordered set/multiset
- Unordered map/multimap
vector的操作分析:
-
增加操作:O(1)
-
插入操作:O(m),因为插入操作会把插入位置后面的元素都会往后移动,所以效率比较低
vector增加元素都是从最后开始增加的,而deque可以从前后两侧追加元素
Deque
void DequeTest(){
deque<int> deq={1,3,45};
deq.push_front(100);
deq.push_front(200);
deq.push_back(300);
for(auto iter=deq.begin();iter!=deq.end();++iter){
cout<<*iter<<endl;
}
}
Properties:
- 从尾部和头部插入和删除操作都是O(1)的复杂度
- 中间插入和删除都是O(n)的复杂度
- 插入的复杂度是O(n)
List
list是双向链表
void listTest(){
list<int> list={5,6,12};
list.push_back(100);
list.push_front(200);
auto itr=find(list.begin(),list.end(),6);
if(itr!=list.end()){
list.insert(itr, 250);//插入操作比list/deque快
}
for(auto index=list.begin();index!=list.end();++index){
cout<<*index<<endl;
}
}
Properties:
- 任意位置快速插入和删除:O(1)
- 查询需要遍历整个链表,需要o(n)
- 因为不是连续存储,所以无法任意访问,没有[]操作符
ForwardList
forwardlist是单向链表,只能向后遍历
Set
set中没有重复的元素,切set中的数据是有序的
void SetTest(){
//set的有序性是有有序二叉树来保证的,所以每一次的插入操作可能会引起二叉树的调整
//所以set的insert操作的复杂度是o(1)
set<int> myset;
myset.insert(10);
myset.insert(20);
myset.insert(130);
myset.insert(4);
for(set<int>::iterator itr=myset.begin();itr!=myset.end();++itr){
cout<<*itr<<endl;
}
//insert操作会返回一个pair<set<x>,bool>
//键值对的第一个值表示插入的元素所在的iterator,第二个值表示插入是否成功
//因为set中的元素是不能重复的,所以每一次的插入操作不一定都会成功。
int invalue=130;
pair<set<int>::iterator, bool> result=myset.insert(invalue);
if(result.second==false){
cout<<"insertion failed"<<endl;
}else{
cout<<"new inserted value is:"<<invalue<<endl;
}
}
Properties:
set中的插入位置无法有用户指定,插入元素的位置只能有被插入元素的key值来确定。set的插入,删除,查询复杂度都是O(long(n))。
set的删除,插入操作可能会引起背后的二叉树的调整。查询操作虽然不会引起树的调整,但是遍历的深度和数量与调整等价。
multiset
multiset和set是一样的,只是multiset允许元素重复。
得益于元素可以重复的特性,multiset的插入操作总是成功的。
mu ltiset中的元素不可修改的,iterator是被const约束
map/multimap
map不允许key重复的键值对。
void MapTest(){
map<char,int> mymap;
mymap.insert(make_pair('c', 12));
mymap.insert(pair<char, int >('d',23));
mymap.insert(make_pair('h', 90));
auto result=mymap.find('h');
//map和multimap中的key值是不可修改的,因为返回的是pair<const char,int>,key值是只读的
// (*result).first='A';//因为iterator被const约束了,所以无法修改
for(map<char, int>::iterator itr=mymap.begin();itr!=mymap.end();++itr){
cout<<"key:"<<(*itr).first<<'\t';
cout<<"value:"<<(*itr).second<<endl;
}
cout<<(*result).second<<endl;
}