zoukankan      html  css  js  c++  java
  • STL容器

    顺序容器:是一种各元素之间有顺序关系的线性表,是一种线性结构的可序群集。顺序性容器中的每个元素均有固定的位置,除非用删除或插入的操作改变这个位置。顺序容器的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定。

    顺序容器包括:vector(向量)、list(列表)、deque(队列)。

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

    vector

    vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。
    vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,
    简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。
    使用vector,必须在你的头文件中包含下面的代码:

    #include <vector>
    

    属于std命名域的,因此需要通过命名限定,如下完成你的代码:

    using std::vector;
    vector vInts;
    或者连在一起,使用全名
    std::vector vInts;
    

    初始化

    vector                 // 创建一个空的vector。
    vector c1(c2)          // 复制一个vector
    vector c(n)            // 创建一个vector,含有n个数据,数据均已缺省构造产生
    vector c(n, elem)      // 创建一个含有n个elem拷贝的vector
    vector c(beg,end)      // 创建一个含有n个elem拷贝的vector
    

    析构函数

    c.~vector ()           // 销毁所有数据,释放内存
    

    成员函数

    c.begin()          // 传回迭代器中的第一个数据地址。
    c.end()            // 指向迭代器中末端元素的下一个,指向一个不存在元素。
    c.push_back(elem)  // 在尾部加入一个数据。
    c.clear()          // 移除容器中所有数据。
    c.empty()          // 判断容器是否为空。
    c.size()           // 返回容器中实际数据的个数。
    c1.swap(c2)        // 将c1和c2元素互换。
    swap(c1,c2)        // 将c1和c2元素互换。同上操作。
    c.capacity()       // 返回容器中数据个数。
    operator[]         // 返回容器中指定位置的一个引用。
    c.max_size()       // 返回容器中最大数据的数量。
    ----------------------------------------------------------------------------------------
    c.front()             // 传回第一个数据。
    c.back()              // 传回最后一个数据,不检查这个数据是否存在。
    c.assign(beg,end)c.assign(n,elem)//将[beg; end)区间中的数据赋值给c。将n个elem的拷贝赋值给c。
    c.at(idx)             //传回索引idx所指的数据,如果idx越界,抛出out_of_range。
    c.erase(pos)          // 删除pos位置的数据,传回下一个数据的位置。
    c.erase(beg,end)      //删除[beg,end)区间的数据,传回下一个数据的位置。
    get_allocator         // 使用构造函数返回一个拷贝。
    c.insert(pos,elem)    // 在pos位置插入一个elem拷贝,传回新数据位置。
    c.insert(pos,n,elem)  // 在pos位置插入n个elem数据。无返回值。
    c.insert(pos,beg,end) // 在pos位置插入在[beg,end)区间的数据。无返回值。 
    c.pop_back()          // 删除最后一个数据。
    c.rbegin()            // 传回一个逆向队列的第一个数据。
    c.rend()              // 传回一个逆向队列的最后一个数据的下一个位置。
    c.resize(num)         // 重新指定队列的长度。
    c.reserve()           // 保留适当的容量。
    

    list

    List定义

    List是stl实现的双向链表,与向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢。使用时需要添加头文件

    #include <list>
    

    List初始化

    list<int>lst1;                           //创建空list
    list<int> lst2(5);                       //创建含有5个元素的list
    list<int>lst3(3,2);                      //创建含有3个元素的list
    list<int>lst4(lst2);                     //使用lst2初始化lst4
    list<int>lst5(lst2.begin(),lst2.end());  //同lst4
    

    List常用操作函数

    Lst1.push_back()      //在list的末尾添加一个元素 
    Lst1.push_front()     //在list的头部添加一个元素 
    Lst1.clear()          //删除所有元素 
    ----------------------------------------------------
    Lst1.assign()         //给list赋值 
    Lst1.back()           //返回最后一个元素 
    Lst1.begin()          //返回指向第一个元素的迭代器 
    Lst1.empty()          //如果list是空的则返回true 
    Lst1.end()            //返回末尾的迭代器 
    Lst1.erase()          //删除一个元素 
    Lst1.front()          //返回第一个元素 
    Lst1.get_allocator()  //返回list的配置器 
    Lst1.insert()         //插入一个元素到list中 
    Lst1.max_size()       //返回list能容纳的最大元素数量 
    Lst1.merge()          //合并两个list 
    Lst1.pop_back()       //删除最后一个元素 
    Lst1.pop_front()      //删除第一个元素 
    Lst1.rbegin()         //返回指向第一个元素的逆向迭代器 
    Lst1.remove()         //从list删除元素 
    Lst1.remove_if()      //按指定条件删除元素 
    Lst1.rend()           //指向list末尾的逆向迭代器 
    Lst1.resize()         //改变list的大小 
    Lst1.reverse()        //把list的元素倒转 
    Lst1.size()           //返回list中的元素个数 
    Lst1.sort()           //给list排序 
    Lst1.splice()         //合并两个list 
    Lst1.swap()           //交换两个list 
    Lst1.unique()         //删除list中重复的元素
    

    deque

    #include <deque>
    

    deque容器类与vector类似,支持随机访问和快速插入删除,它在容器中某一位置上的操作所花费的是线性时间。与vector不同的是,deque还支持从开始端插入数据:push_front()。其余类似vector操作方法的使用。

    顺序容器通用方法

    添加元素

    c.push_back(t)  	//在容器c的尾部添加值为t的元素。返回void 类型
    c.push_front(t) 	//在容器c的前端添加值为t的元素。返回void 类型只适用于list和deque容器类型。
    c.insert(p,t)   	//在迭代器p所指向的元素前面插入值为t的新元素。返回指向新添加元素的迭代器。
    c.insert(p,n,t) 	//在迭代器p所指向的元素前面插入n个值为t的新元素。返回void 类型
    c.insert(p,b,e) 	//在迭代器p所指向的元素前面插入由迭代器b和e标记的范围内的元素。返回 void 类型
    

    容器大小操作

    c.size()       //返回容器c中元素个数。返回类型为 c::size_type
    c.max_size()   //返回容器c可容纳的最多元素个数,返回类型为c::size_type
    c.empty()      //返回标记容器大小是否为0的布尔值
    c.resize(n)    //调整容器c的长度大小,使其能容纳n个元素,如果n<c.size(),则删除多出来的元素。
    c.resize(n,t)  //调整容器c的长度大小,使其能容纳n个元素。所有新添加的元素值都为t
    

    访问元素

    c.back()        //返回容器 c 的最后一个元素的引用。如果 c 为空,则该操作未定义
    c.front()       //返回容器 c 的第一个元素的引用。如果 c 为空,则该操作未定义
    c[n]            //返回下标为 n 的元素的引用。如果下标越界,则该操作未定义只适用于 vector 和 deque 容器
    c.at(n)         //返回下标为 n 的元素的引用。如果下标越界,则该操作未定义只适用于 vector 和 deque 容器
    

    删除元素

    c.erase(p)    //删除迭代器p所指向的元素。返回一个迭代器,它指向被删除元素后面的元素。
    c.erase(b,e)  //删除迭代器b和e所标记的范围内所有的元素。返回一个迭代器,它指向被删除元素段后面的元素。
    c.clear()     //删除容器c内的所有元素。返回void。
    c.pop_back()  //删除容器c的最后一个元素。返回void。如果c为空容器,则该函数未定义。
    c.pop_front() //删除容器c的第一个元素。返回void。如果c为空容器,则该函数未定义只适用于list或deque容器。
    

    赋值和交换

    c1 = c2   //删除容器c1的所有元素,然后将c2的元素复制给c1。c1和c2的类型(包括容器类型和元素类型)必须相同
    c1.swap   //(c2)交换c1和c2的内容,比赋值操作速度快。
    c.assign  //(b,e)将迭代器b和e标记的范围内所有的元素复制到c中。b和e必须不是指向c中元素的迭代器
    c.assign  //(n,t)将容器c重新设置为存储n个值为t的元素
    

    关联式容器是非线性的树结构,更准确的说是二叉树结构。各元素之间没有严格的物理上的顺序关系,也就是说元素在容器中并没有保存元素置入容器时的逻辑顺序。但是关联式容器提供了另一种根据元素特点排序的功能,这样迭代器就能根据元素的特点“顺序地”获取元素。元素是有序的集合,默认在插入的时候按升序排列。

    关联容器包括:map(集合)、set(映射)、multimap(多重集合)、multiset(多重映射)。

    map

    map容器提供一个键值对(key/value)容器,map与multimap差别仅仅在于multiple允许一个键对应多个值。对于迭代器来说,可以修改实值,而不能修改key。Map会根据key自动排序。
    map 是键-值对的集合。map 类型通常可理解为关联数组:可使用键作为下标来获取一个值,正如内置数组类型一样。而关联的本质在于元素的值与某个特定的键相关联,而并非通过元素在数组中的位置来获取。

    初始化

    #include <map>
    
    map<k, v>m        //创建一个名为m的空map对象,其键和值的类型分别为k和v
    map<k, v>m(m2)    //创建m2的副本m,m与m2必须有相同的键类型和值类型
    map<k, v>m(b, e)  //创建map类型的对象m,存储迭代器b和e标记的范围内所有元素的副本,
                      //元素的类型必须能转换为pair<const k, v>。
    

    在使用关联容器时,它的键不但有一个类型,而且还有一个相关的比较函数。所用的比较函数必须在键类型上定义严格弱排序(strict weak ordering):可理解为键类型数据上的“小于”关系,虽然实际上可以选择将比较函数设计得更复杂。对于键类型,唯一的约束就是必须支持 < 操作符,至于是否支持其他的关系或相等运算,则不作要求。

    方法

    添加元素有两种方法:1、先用下标操作符获取元素,然后给获取的元素赋值 2、使用insert成员函数实现
    下标操作添加元素:如果该键已在容器中,则 map 的下标运算与 vector 的下标运算行为相同:返回该键所关联的值。只有在所查找的键不存在时,map 容器才为该键创建一个新的元素,并将它插入到此 map 对象中。此时,所关联的值采用值初始化:类类型的元素用默认构造函数初始化,而内置类型的元素初始化为 0。

    m insert(e)    //e是一个用在m上的value_type 类型的值。如果键(e first不在m中,则插入一个值为e second 
                   //的新元素;如果该键在m中已存在,则保持m不变。该函数返回一个pair类型对象,包含指向键为
                   //e first的元素的map迭代器,以及一个 bool 类型的对象,表示是否插入了该元素
    -------------------------------------------------------------------------------------------
    m insert(beg,end)//beg和end是标记元素范围的迭代器,其中的元素必须为m value_type 类型的键-值对。对于
                     //该范围内的所有元素,如果它的键在m中不存在,则将该键及其关联的值插入到m。返回void类型
    -------------------------------------------------------------------------------------------
    m insert(iter,e)//e是一个用在m上的 value_type 类型的值。如果键(e first)不在m中,则创建新元素,并以
                    //迭代器iter为起点搜索新元素存储的位置。返回一个迭代器,指向m中具有给定键的元素
    

    遍历

    map中使用下标存在一个很危险的副作用:如果该键不在 map 容器中,那么下标操作会插入一个具有该键的新元素。所以map 容器提供了两个操作:count 和 find,用于检查某个键是否存在而不会插入该键。

    m count(k)   //返回 m 中 k 的出现次数
    m find(k)    //如果m容器中存在按k索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端迭代器。
    

    删除

    m erase(k)      //删除m中键为k的元素。返回size_type类型的值,表示删除的元素个数
    m erase(p)      //删除p所指向的元素。p必须指向m中确实存在的元素,而且不能等于m end()。返回void
    m erase(b,e)    //从m中删除一段范围内的元素,该范围由迭代器对b和e标记。b和e必须标记m中的一段有效范围:即b和e都必须指向m中的元素或最后一个元素的下一个位置。而且,b和e要么相等(此时删除的范围为空),要么b所指向的元素必须出在e所指向的元素之前。返回 void 类型
    

    set

    set的含义是集合,它是一个有序的容器,里面的元素都是排序好的,支持插入,删除,查找等操作,就像一个集合一样。所有的操作的都是严格在logn时间之内完成,效率非常高。set和multiset的区别是:set插入的元素不能相同,但是multiset可以相同。Set默认自动排序。使用方法类似list。

    begin()              //返回指向第一个元素的迭代器
    clear()              //清除所有元素
    count()              //返回某个值元素的个数
    empty()              //如果集合为空,返回true
    end()                //返回指向最后一个元素的迭代器
    equal_range()        //返回集合中与给定值相等的上下限的两个迭代器
    erase()              //删除集合中的元素
    find()               //返回一个指向被查找到元素的迭代器
    get_allocator()      //返回集合的分配器
    insert()             //在集合中插入元素
    lower_bound()        //返回指向大于(或等于)某值的第一个元素的迭代器
    key_comp()           //返回一个用于元素间值比较的函数
    max_size()           //返回集合能容纳的元素的最大限值
    rbegin()             //返回指向集合中最后一个元素的反向迭代器
    rend()               //返回指向集合中第一个元素的反向迭代器
    size()               //集合中元素的数目
    swap()               //交换两个集合变量
    upper_bound()        //返回大于某个值元素的迭代器
    value_comp()         //返回一个用于比较元素间的值的函数
    

    举个栗子:

    #include<set>
    #include<iostream>
    using namespace std;
    int main()
    {
        int i;
        int arr[5] = {0,1,2,3,4};
        set<int> iset(arr,arr+5);
    
        iset insert(5);
        cout<<"size:"<<iset size()<<endl;
        cout<<"3 count = "<<iset count(3)<<endl;
        iset erase(1);
    
        set<int>::iterator ite1 = iset begin();
        set<int>::iterator ite2 = iset end();
        for(;ite1!=ite2;ite1++)
        {
            cout<<*ite1;
        }
        cout<<endl;
    
        ite1 = iset find(3);
        if(ite1!=iset end())
            cout<<"3 found"<<endl;
    
        ite1 = iset find(1);
        if(ite1!=iset end())
            cout<<"1 not found"<<endl;
    }
    

    参考链接:
    https://www.jianshu.com/p/fe909c102c08
    https://www.jb51.net/article/115201.htm
    https://blog.csdn.net/u014465639/article/details/70241850

  • 相关阅读:
    一对多关系处理
    java中转换不同时区的时间
    maven
    学习设计模式
    算法
    mongodb学习总结
    mybatis源码分析(四) mybatis与spring事务管理分析
    学习数据库四大特性及事务隔离级别
    mybatis源码分析(三) mybatis-spring整合源码分析
    mybatis源码分析(二) 执行流程分析
  • 原文地址:https://www.cnblogs.com/chendeqiang/p/12861593.html
Copyright © 2011-2022 走看看