stl不同容器的优缺点
verctor
vector类似于C语言中的数组,它维护一段连续的内存空间,具有固定的起始地址,因而能非常方便地进行随机存取,即 [] 操作符,但因为它的内存区域是连续的,所以在它中间插入或删除某个元素,需要复制并移动现有的元素。此外,当被插入的内存空间不够时,需要重新申请一块足够大的内存并进行内存拷贝。值得注意的是,vector每次扩容为原来的两倍,对小对象来说执行效率高,但如果遇到大对象,执行效率就低了。
list
list类似于C语言中的双向链表,它通过指针来进行数据的访问,因此维护的内存空间可以不连续,这也非常有利于数据的随机存取,因而它没有提供 [] 操作符重载。
deque
deque类似于C语言中的双向队列,即两端都可以插入或者删除的队列。queue支持 [] 操作符,也就是支持随机存取,而且跟vector的效率相差无几。它支持两端的操作:push_back,push_front,pop_back,pop_front等,并且在两端操作上与list的效率
也差不多。或者我们可以这么认为,deque是vector跟list的折中。
map
map类似于数据库中的1:1关系,它是一种关联容器,提供一对一的数据处理能力,这种特性了使得map类似于数据结构里的红黑二叉树。
multimap
multimap类似于数据库中的1:N关系,它是一种关联容器,提供一对多的数据处理能力。
set
set类似于数学里面的集合,不过set的集合中不包含重复的元素,这是和vector的第一个区别,第二个区别是set内部用平衡二叉树实现,便于元素查找,而vector是使用连续内存存储,便于随机存取。
multiset
multiset类似于数学里面的集合,集合中可以包含重复的元素。
小结
在实际使用过程中,到底选择这几种容器中的哪一个,应该根据遵循以下原则:
1、如果需要高效的随机存取,不在乎插入和删除的效率,使用vector;
2、如果需要大量的插入和删除元素,不关心随机存取的效率,使用list;
3、如果需要随机存取,并且关心两端数据的插入和删除效率,使用deque;
4、如果打算存储数据字典,并且要求方便地根据key找到value,一对一的情况使用map,一对多的情况使用multimap;
5、如果打算查找一个元素是否存在于某集合中,唯一存在的情况使用set,不唯一存在的情况使用multiset。
map:
map是STL的关联容器,和set一样 。每个节点内容是一个pair,pair第一元素称作“键值”,第二个称作实值,它提供一对一的数据映射。特点是所有元素会根据键值自动被排序,因为底层数据结构采用红黑树。它是一种平衡二叉树,可以对节点自动排序。并且map的各种操作接口,rb-tree都提供了,所以几乎map所有操作都是转调用rb-tree的操作。。
1.提供6个构造函数
map(); // 默认构造函数
map(const map& m) // 拷贝构造函数
map(iterator begin, iterator end ); //区间构造函数
map(iterator begin, iterator end, const traits& _compare) //带比较谓词的构造函数
map(iterator begin, iterator end, const traits& _compare, const allocator& all) //带分配器
2.插入数据
Map<int,string> mapStudent;
第一种:用insert函数插入pair数据,mapStudent.insert(pair<int,string>(1,"student_one"));
第二种:用insert函数插入value_type数据,mapStudent.insert(map<int,string>::value_type (1,"student_one"));
第三种:用数组方式插入数据, mapStudent[1] = “student_one”;
3. map的大小
使用size()函数
4. 数据的遍历
第一种:应用前向迭代器,最常见
map<int,string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
{
cout<<iter->first<<" "<<iter->second<<endl;
}
第二种:应用反相迭代器,
map<int,string>::reverse_iterator iter;
for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)
{
cout<<iter->first<<" "<<iter->second<<endl;
}
第三种:用数组方式
int nSize = mapStudent.size()
for(int nIndex = 1; nIndex <= nSize; nIndex++)
{
cout<<mapStudent[nIndex]<<end;
}
5. 查找
第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置。其返回值只有两个,要么是0,要么是1,出现返回1.
第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器
6. 清空与判空
清空map中的数据可以用clear()函数,判定map中是否有数据可以用empty()函数,它返回true则说明是空map
7.删除
用迭代器删除
用关键字删除
成片的删除
8.排序
STL容器操作总结。链接:https://blog.csdn.net/xgf415/article/details/52939005