zoukankan      html  css  js  c++  java
  • STL容器(Stack, Queue, List, Vector, Deque, Priority_Queue, Map, Pair, Set, Multiset, Multimap)

    一、Stack(栈)

    • 这个没啥好说的,就是后进先出的一个容器。
    • 基本操作有:
    1     stack<int>q;
    2     q.push(1);   //入栈
    3     q.pop();     //出栈
    4     q.top();     //返回栈顶成员
    5     q.size();    //返回栈成员个数
    6     q.empty();   //判断是否为空栈

    二、Queue(队列)

    • 同上,先进先出的容器
    • 基本操作有:
    1     queue<int>q;
    2     q.push(1);    //入队列
    3     q.pop();      //出队列
    4     q.front();    //返回最上面(最后进入)的成员
    5     q.size();     //返回队列成员个数
    6     q.empty();    //判断是否为空队列

    三、Priority_Queue(优先队列)

    • priority_queue的模板生命是带有三个参数的:priority_queue<type,container,function>
    • 和队列差不多,不过每个成员都有一个优先级参数,队列按照优先级进行排序
    • 默认container是vector,默认function比较模式为operator <(即栈顶为最大值)。
    • 基本操作有:
    1     priority_queue<int,vector<int>,greater<int> >q;
    2     q.push(1);    //入优先队列
    3     q.top();      //返回优先队列头成员
    4     q.pop();      //出优先队列
    5     q.size();     //返回优先队列成员个数
    6     q.empty();    //判断是否为空优先队列
    • 内置的排序方式有greater<>,和less<>,不填此参数默认为greater<>。当然也可以自己构造优先级函数
    • 例如对结构体重载运算符:
    1     struct node{
    2         int x,y;
    3         
    4         //重载运算符,按x的值排优先级
    5         friend operator < (node a,node b){
    6             return a.x < b.x;
    7         }
    8     };
    • 也可以将重载操作写在外面,优先队列中调用cmp函数
     1     struct node{
     2         int x,y;
     3     };
     4     struct cmp{
     5         //重载运算符,按x的值排优先级
     6         bool operator() (node a,node b){
     7             return a.x < b.x;
     8         }
     9     };
    10 
    11     priority_queue<node,vector<node>,cmp >q;

    四、Deque(双向队列)

    • 一听就知道和Queue差不多 ,特殊的是Deque可是扩充内存。我们知道连续内存的容器不能随意扩充,所以Deque也不是真正意义上的扩充内存。
    • Deque是由一段一段构成的,当走到尾端时自动跳到下一段,(支持迭代器++操作)。每次扩充,申请一个段,实现了内存连续的假象。
    • 基本操作有:
     1     int num[] = {1,2,3,4,5,6};
     2     deque<int>q;        //创建一个空双向队列
     3     deque<int>p(5);     //创建一个具有5个成员的双向队列
     4     deque<int>s(5,1);   //创建一个具有5个成员且初始值为1的双向队列
     5     deque<int>s2(s);    //创建一个双向队列s2,并拷贝s中所有成员
     6     deque<int>n(num,num+5); //创建一个双向队列n,并拷贝num至num+5中元素入队
     7     
     8     q.push_front(a);     //头部入队
     9     q.pop_back(b);     //尾部入队
    10     q.insert(iter,x);   //在iter位置插入x,iter为迭代器
    11     q.pop_front();       //头部出队
    12     q.pop_back();      //尾部出队
    13     
    14     q.front();          //返回头成员
    15     q.back();           //返回尾元素
    16     q.size();           //返回双向队列成员个数
    17     q.max_size();       //返回系统支持成员最大个数
    18     q.empty();          //判断双向队列是否为空
    19     
    20     q.at(i);            //返回第i个元素
    21     q.begin();          //返回头部迭代器
    22     q.end();            //返回尾部迭代器
    23     q.rbegin();         //返回尾部反向迭代器
    24     q.rend();           //返回头部反向迭代器
    25     
    26     q.erase(iter);      //删除iter元素,iter为迭代器
    27     q.clear();          //情况双向队列
    28     q.swap(p);          //交换q和p中的所有元素
    •  Deque采用分块线型结构存储数据,两个迭代器分别指向首尾元素,而且拥有具有高效的push_back(),push_front()函数。
    •  正因如此,所以Deque不易实现capacity和reverse函数。
    • Deque的缺点:频繁的插入删除时候,Deque并不适合。

    五、Vector(动态数组)

    • 顾名思义,不定长数组。
    • uhmmm没啥好说的
    • 基本操作有:
     1     vector<int>q;           //创建空Vector
     2     vector<int>p(5);        //创建拥有5个成员的Vector
     3     vector<int>s(5,1);      //创建拥有5个成员,且初始值为1的Vector
     4     vector<int>s2(s);       //创建s2,并拷贝s元素给s2
     5     vector<int>s3(s.begin(),s.end());   //创建s3,拷贝s.begin()至s.end()中元素给s3
     6     
     7     q.push_back(x);          //尾部加入元素
     8     q.insert(iter,x);        //在iter位置插入x,传回新数据位置
     9     q.insert(iter,n,x);      //在iter位置插入n个x,无返回值
    10     q.insert(iter,l,r);      //在iter位置插入[l,r)区间内的数据,无返回值
    11     q.pop_back();            //删除最后一个元素
    12     q.front();               //返回第一个数据
    13     q.back();                //返回最后一个数据
    14 
    15     q.size();                //返回容器内成员个数
    16     q.resize(x);              //重新指定容器大小
    17     q.empty();               //判断Vector是否为空
    18     q.capacity();            //返回Vector可用空间的大小
    19     q.reserve();             //重新指定空间大小,小于当前capacity时保持为原本的capacity值
    20     q.swap(p);               //交换p,q容器内元素
    21     q.assign(iter1,iter2);   //将区间[iter1,iter2)内元素赋值给vector,并清空vector容器之前的内容。
    22     q.assign(n,x);           //将n个x赋值到vector中,并清空vector容器之前的内容。
    23     
    24     q.at(i);                 //返回第i个元素
    25     q.begin();               //返回头位置迭代器
    26     q.end();                 //返回尾位置迭代器
    27     q.rbegin();              //返回尾部反向迭代器
    28     q.rend();                //返回头部反向迭代器
    29 
    30     q.clear();               //情况Vector
    31     q.erase();               //删除iter位置元素
    32     q.erase(iter1,iter2);    //删除[iter1,iter2)区间内的元素
    • 此外,vector还可以用数组的方式引用,因为以及内置重载了[],例如q[0]等同于q.at(1)。

    六、List(链表)

    • 链表其实用的不多
    • 自己也没怎么用过 =7= 直接放代码操作了
    • 基本操作:
     1     list<int>q;           //创建空List
     2     list<int>p(5);        //创建拥有5个成员的List
     3     list<int>s(5,1);      //创建拥有5个成员,且初始值为1的List
     4     list<int>s2(s);       //创建s2,并拷贝s元素给s2
     5     list<int>s3(s.begin(),s.end());   //创建s3,拷贝s.begin()至s.end()中元素给s3
     6 
     7     q.back()                 //返回最后一个元素 
     8     q.begin()                //返回指向第一个元素的迭代器 
     9     q.clear()                //删除所有元素 
    10     q.empty()                //如果list是空的则返回true 
    11     q.end()                  //返回末尾的迭代器 
    12     q.erase()                //删除一个元素 
    13     
    14     q.front()                //返回第一个元素 
    15     q.get_allocator()        //返回list的配置器 
    16     q.insert()               //插入一个元素到list中 
    17     q.max_size()             //返回list能容纳的最大元素数量 
    18     q.merge()                //合并两个list 
    19     q.pop_back()             //删除最后一个元素 
    20     q.pop_front()            //删除第一个元素 
    21     q.push_front()           //在list的头部添加一个元素 
    22     
    23     q.rbegin()               //返回指向第一个元素的逆向迭代器 
    24     q.remove()               //从list删除元素 
    25     q.remove_if()            //按指定条件删除元素 
    26     q.rend()                 //指向list末尾的逆向迭代器 
    27     q.resize()               //改变list的大小 
    28     q.reverse()              //把list的元素倒转 
    29     q.size()                 //返回list中的元素个数 
    30     q.sort()                 //给list排序 
    31     q.splice()               //合并两个list 
    32     q.swap()                 //交换两个list 
    33     q.unique()               //删除list中重复的元素

    七、Pair(对)

    • 就是合成两个数据,这个用结构体模拟也行,但是直接使用Pair会方便很多
    • 基本操作如下:
    1     pair<int,int>q;     //创建一个空对
    2     pair<int,int>p(2,3);//创建一个对p,并分别赋值2,3
    3     pair<int,int>s(p);  //创建一个对s,拷贝p给s
    4     
    5     //赋值利用make_pair函数
    6     q = make_pair(1,2);
    7     //访问pair内元素操作
    8     q.first;        //返回成员第一个数据
    9     q.second;       //返回成员第二个数据

    八、Set(集合)

    • 首先Set遵循数学集合三特性,无重复、无序性、确定性。我就不解释了。
    • Set中内置红黑树进行排序,所以插入删除效率很高。
    • 常用操作如下:
     1     int a[] = {1,2,3,4,5};
     2     set<int>q;
     3     set<int>p;
     4     
     5     q.insert(x);      //集合中插入元素
     6     q.insert(a,a+5);  //插入数组a至a+5的元素
     7     q.find(x);        //返回x值位置的迭代器,找不到返回q.end()  
     8     q.erase(iter);    //删除集合中的元素
     9     q.size();         //返回当前set容器中的元素个数
    10     q.count();        //返回某个值元素的个数(根据set的特性,就是判断这个元素在不在,返回0或1)
    11     q.begin();        //返回头位置迭代器
    12     q.end();          //返回尾位置迭代器
    13     q.rbegin();       //返回尾部反向迭代器
    14     q.rend();         //返回头部反向迭代器
    15     q.clear();        //删除set容器中的所有的元素
    16     q.empty();        //判断set容器是否为空
    17     q.lower_bound();  //返回指向大于(或等于)某值的第一个元素的迭代器
    18     q.upper_bound();  //返回大于某个值元素的迭代器
    • 当然,你也可以自定义Set内部的排序操作,例如:
    1     struct cmp{
    2         bool operator() (const node &a,const node &b){
    3             return a.x < b.x;
    4         }
    5     };
    6     
    7     set<node,cmp>q;

    九、Map

    • 不知道该翻译成啥,干脆不翻译了 =7=
    • map是一种关联容器,例如map<int,int>,第一个元素可以称为关键字,类似数组的下标,不会重复出现,而第二个元素为关键字的值,类似数组中存的元素,可以重复。
    • map不能直接修改关键字,只能通过修改关键字的值间接修改关键字。
    • 和Set一样,map也是内置红黑树对关键字进行排序。能够实现快速查找和删除功能。
    • 基本操作:
     1     map<int,int>q;
     2     
     3     q.insert(pair<int,int>(1,2));       //通过pair进行插入操作
     4     q.insert(map<int,int>::value_type (1,2));//通过value_type进行插入
     5     q[1] = 2;           //用数组方式进行插入
     6     /*三者不同的是,当map存在这个关键字时
     7      *数组方式会覆盖关键字的值,而insert操作无法插入。
     8     */
     9     
    10     q.size();       //返回容器内元素个数
    11     q.empty();      //判断容器是否为空 
    12     q.begin();      //返回头位置迭代器
    13     q.end();        //返回尾位置迭代器
    14     q.rbegin();     //返回尾部反向迭代器
    15     q.rend();       //返回头部反向迭代器
    16     q.find(key);    //查找并返回关键字key的位置
    17     q.count(key);   //查询是否有关键字key(有则返回1,否则0)
    18     q.lower_bound();//返回键值>=给定元素的第一个位置
    19     q.upper_bound();//返回键值>给定元素的第一个位置
    20     q.erase(iter);  //删除迭代器iter的元素
    21     q.erase(iter1,iter2);//删除[iter1,iter2)区间内的元素
    22     q.erase(key);   //删除关键字为key的元素
    23     q.clear();      //清空容器
    24     q.swap(p);      //交换两个map
    25     q.key_comp();   //返回比较元素key的函数
    26     q.max_size();   //返回可以容纳的最大元素个数
    27     q.value_comp(); //返回比较元素value的函数
    28     q.equal_range();//返回特殊条目的迭代器对
    • 当然你可以自己写内部排序函数
    • 例如结构体中重载<号,或者编写仿函数,例如:
    1 class sort{
    2 
    3 public:
    4     bool operator() (node const &a,node const &b) const{
    5         return a.x < b.x;
    6     }
    7 
    8 };

    十、Multiset(多重集合)

    • 和Set不同的地方是Multiset允许一个值出现多次;
    • 操作和set相同。但是因为值能重复出现,所有某些函数的返回值将会改变,例如:
    • multiset::count(key)返回值可能大于1;(多个关键值存在)
    • multiset::erase(key)会将对应的key全部删掉。
    • 对于set总是有set::equal_range(key)的返回值总有++iter1 = iter2.但multiset不一定(元素相同)

    十一、Multimap

    • 同上,和map类似,可以存在相同的关键字。

    本来想讲BitSet,但是觉得bitset比较特殊,到时候专门详细讲吧。

    其实所有容器都挺简单的,根据特性基本都能想出操作。熟悉了这些容器之后,对做题和学习很有帮助的。

    记住操作没啥用,得不断的练习使用这些容器 ,才能熟练操作。

    emmmm都说的很简陋,本来想讲每个容器的具体实现一起构造方式。后来一想,篇幅太长了,还容易误导别人觉得容器很复杂。这些都算是学个表面吧,最重要的还是不断敲敲敲,熟悉各种用法。

    大致就这样吧 =7=


     后续:Stack,Queue,Pair并不是C++的标准容器,但是我觉得性质差不多,就一起讲了,但是防止误导初学者,这里还是提一下。

  • 相关阅读:
    CentOS
    Docker
    Chart的简单使用
    DataGridView中间插入数据行
    获取每个月的固定的第n个星期几
    设置只能开启一个程序实例
    DataContext与实体类
    Attribute
    Delegate
    Event
  • 原文地址:https://www.cnblogs.com/xenny/p/9362743.html
Copyright © 2011-2022 走看看