C++ STL容器使用总结

今天第一次接触到STL,觉得实在太厉害了,但是东西好多我怕我记不住,还是总结一下。

以后关于STL的东西都会陆续总结在这里,不过大多都是我从别的大佬那里看到的,我目前用到过的然后整理到一起。

 

目录

一、顺序容器

1、vector

2、list

二、关联容器

1、set

2、map

三、容器适配器

1、stack

2、queue

3、priority_queue


标准容器类

特点

顺序性容器

vector

从后面快速的插入与删除,直接访问任何元素

deque

从前面或后面快速的插入与删除,直接访问任何元素

list

双链表,从任何地方快速插入与删除

关联容器

set

快速查找,不允许重复值

multiset

快速查找,允许重复值

map

一对多映射,基于关键字快速查找,不允许重复值

multimap

一对多映射,基于关键字快速查找,允许重复值

容器适配器

stack

后进先出

queue

先进先出

priority_queue

最高优先级元素总是第一个出列

 

 

 

  c++中有两种类型的容器:顺序容器关联容器顺序容器主要有:vector、list、deque等。其中vector表示一段连续的内存地址,基于数组的实现,list表示非连续的内存,基于链表实现。deque与vector类似,但是对于首元素提供删除和插入的双向支持。关联容器主要有map和set。map是key-value形式的,set是单值。map和set只能存放唯一的key值,multimap和multiset可以存放多个相同的key值。

容器类自动申请和释放内存,我们无需new和delete操作。

 

一、顺序容器

容器的选择:vector和deque容器提供了对元素的快速随机访问,但付出的代价是在容器的任意位置插入或删除元素,比在容器尾部插入和删除的开销更大。list类型在任何位置都能快速插入和删除,但付出的代价是元素的碎甲访问开销较大。

1、vector

需要包含头文件#include<vector>

我对vector的理解其实就是可变长数组,就像java里的vector类,并且在这个容器里添加了很多实用的方法,还挺方便的,比单纯使用数组去自己写各种函数不知道方便多少倍,并且就像java中的泛型类一样,可以供不同数据类型使用,可以说是很棒了。

//1.定义和初始化
     vector<int> vec1;    //默认初始化,vec1为空
     vector<int> vec2(vec1);  //使用vec1初始化vec2
     vector<int> vec3(vec1.begin(),vec1.end());//使用vec1初始化vec2
     vector<int> vec4(10);    //10个值为0的元素
     vector<int> vec5(10,4);  //10个值为4的元素
  
//2.常用操作方法
     vec1.push_back(100);            //尾部添加元素
     int size = vec1.size();         //元素个数
     bool isEmpty = vec1.empty();    //判断是否为空
     cout<<vec1[0]<<endl;        //取得第一个元素
     vec1.insert(vec1.end(),5,3);    //从vec1.back位置插入5个值为3的元素(即指向位置之前)
     vec1.pop_back();              //删除末尾元素
     vec1.erase(p)    //删除迭代器p所指向的元素,返回一个迭代器,指向被删除元素后面的元素
     vec1.erase(vec1.begin(),vec1.begin()+2);//删除vec1[0]-vec1[2]之间的元素,它指向被删除元素段内所有的元素
     cout<<(vec1==vec2)?true:false;  //判断是否相等==、!=、>=、<=...
     vector<int>::iterator iter = vec1.begin();    //获取迭代器首地址
     vector<int>::const_iterator c_iter = vec1.begin();   //获取const类型迭代器
     vec1.clear();                 //清空元素
     vec1.resize(n);            //调整vec1的长度大小,使其能容纳n个元素,如果n<vec1.size(),则删除多出来的元素;否则,添加采用值初始化的新元素
     vec1.resize(n,t);           //调整容器vec1的大小,使其能容纳n个元素,所有新添加的元素值为t
  
     vec1.assign(b,e);         //重新设置vec1的元素:将迭代器b和e标记的范围内所有的元素复制到vec1中,b和e必须不是指向c中元素的迭代器
     vec1.assign(n,t);         //将容器vec1重新设置为存储n个值为t的元素


//3.遍历
     //下标法
    int length = vec1.size();
     for(int i=0;i<length;i++)
     {
        cout<<vec1[i];
     }
     cout<<endl<<endl;
     //迭代器法
    vector<int>::iterator iter = vec1.begin();
     for(;iter != vec1.end();iter++)
     {
        cout<<*iter;
     }

 

2、list

list是stl实现的双向链表,与向量vector想比,它允许快速的插入和删除,但是随机访问却是比较慢,需要添加头文件#include<list>

//1.定义和初始化
    list<int> lst1;          //创建空list
    list<int> lst2(3);       //创建含有三个元素的list
    list<int> lst3(3,2); //创建含有三个元素为2的list
    list<int> lst4(lst2);    //使用lst2初始化lst4
    list<int> lst5(lst2.begin(),lst2.end());  //同lst4
 
    //2.常用操作方法
    lst1.assign(lst2.begin(),lst2.end());  //分配值,3个值为0的元素
    lst1.push_back(10);                    //末尾添加值
    lst1.push_front(10);                   //前面添加值
    lst1.pop_back();                   //删除末尾值
    lst1.begin();                      //返回首值的迭代器
    lst1.end();                            //返回尾值的迭代器
    lst1.clear();                      //清空值
    bool isEmpty1 = lst1.empty();          //判断为空
    lst1.erase(lst1.begin(),lst1.end());                        //删除元素
    lst1.front();                      //返回第一个元素的引用
    lst1.back();                       //返回最后一个元素的引用
    lst1.insert(lst1.begin(),3,2);         //从指定位置插入个3个值为2的元素
    lst1.rbegin();                         //返回第一个元素的前向指针
    lst1.remove(2);                        //相同的元素全部删除
    lst1.reverse();                        //反转
    lst1.size();                       //含有元素个数
    lst1.sort();                       //排序
    lst1.unique();                         //删除相邻重复元素
 
    //3.遍历
    //迭代器法
    for(list<int>::const_iterator iter = lst1.begin();iter != lst1.end();iter++)
    {
       cout<<*iter;
    }

注意:

1.不要存储end操作返回的迭代器,添加或删除deque或vector容器内的元素都会导致存储的迭代器失效。

 

二、关联容器

1、set

set容器只是单纯的键的集合。当只想知道一个值是否存在时,使用set容器是最适合。需要包含头文件#include<set>

并且set中的键是唯一的,元素默认按升序排列。

//1.set容器的定义和使用

vector<int> ivec(20);
for ( int i=0; i<10; ++i )
{
    ivec[2*i] = i;
    ivec[2*i+1] = i;
}
// iset holds unique elements form ivec
set<int> iset( ivec.begin(), ivec.end() );
cout << ivec.size() << endl; // prints 20
cout << iset.size() << endl; // prints 10



//2.set容器的基本操作 
set<int>s; 
s.begin()      //返回set容器的第一个元素
s.end()      //返回set容器的最后一个元素
s.clear()       //删除set容器中的所有的元素
s.empty()     //判断set容器是否为空
s.insert()      //插入一个元素
s.erase()       //删除一个元素
s.size()     //返回当前set容器中的元素个数
s.find()          //返回一个指向被查找到元素的迭代器
s.count()          //返回某个值元素的个数,其值只能是0或1 

详见:https://blog.csdn.net/fengzhizi76506/article/details/54810086

 

2、map

自动建立Key - value的对应。key 和 value可以是任意你需要的类型。需要包含头文件#include<map>

详见:https://www.cnblogs.com/yutongzhu/p/5884269.html

 

三、容器适配器

1、stack

C++ Stack(堆栈) 是一个容器类的改编,为程序员提供了堆栈的全部功能,——也就是说实现了一个先进后出(FILO)的数据结构。需要包含头文件#include<stack>

 

empty() //堆栈为空则返回真
pop() //移除栈顶元素
push() //在栈顶增加元素
size() //返回栈中元素数目
top() //返回栈顶元素

 

2、queue

定义了先进先出的队列数据结构。需要包含头文件#include<queue>

 

back() //返回最后一个元素
empty() //如果队列空则返回真
front() //返回第一个元素
pop() //删除第一个元素
push() //在末尾加入一个元素
size() //返回队列中元素的个数

 

 

3、priority_queue

优先队列是队列的一种,所以需要包含头文件#include<queue>

优先队列虽然是个队列,但严格意义上来说已经不是了,它强调的是“优先”,本来队列是先进先出的选择,现在变成了谁的优先级高谁就先出。

 

priority_queue<Type,Container,Compare>    
    
//  Type 为数据类型     
//  Container 为保存数据的容器, 必须是用数组实现的容器,比如 vector, deque 但不能用list。STL里面默认用的是 vector    
//  Compare为元素比较方式。比较方式默认用 operator< , 所以如果你把后面俩个参数缺省的话,优先队列就是大顶堆,队头元素最大。

//所以如果要让小的数据先出队列的话,STL里面定义了一个仿函数 greater<>,对于基本类型可以用这个仿函数声明小顶堆。
priority_queue<int, vector<int>, greater<int> > q;

q.empty();  //如果优先队列为空,则返回真 
q.pop();   //删除第一个元素 
q.push(x) // 加入一个元素 x
q.size()  //返回优先队列中拥有的元素的个数 
q.top()  //返回优先队列中有最高优先级的元素 

 

但是在使用时必须注意:priority_queue放置元素时,不会判断元素是否重复。(因为在模板的第二个参数时顺序容器,不能保证元素的唯一性)此外可以替代默认的Compare函数。

 

1.lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

lower_bound(a,a+n,x)-a 即返回a数组的第一个大于或等于x元素的位置

2.upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

upper_bound(a,a+n,x)-a 即返回a数组的第一个大于x元素的位置

点击打开链接

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值