STL标准模板库

STL的一个重要特点是数据结构和算法的分离
尽管这是个简单的概念,但这种分离确实使得STL变得非常通用。例如,由于STL的sort()函数是完全通用的,你可以用它来操作几乎任何数据集合,包括链表,容器和数组

STL另一个重要特性是它不是面向对象的
为了具有足够通用性,STL主要依赖于模板而不是封装,继承和多态(虚函数)——OOP的三个要素。你在STL中找不到任何明显的类继承关系。这好像是一种倒退,但这正好是使得STL的组件具有广泛通用性的底层特征。另外,由于STL是基于模板,内联函数的使用使得生成的代码短小高效

(重要知识点(10种):
序列式容器:(3种)vector、deque、list
关联式容器:(4种)set、multiset、map、multimap
顺序容器适配器:(3种)queue、priority_queue、stack)

STL中六大组件:

容器,迭代器,算法,仿函数,适配器,分配器

容器

STL中的容器有序列式容器,关联式容器,容器适配器,位集和串包等
容器类自动申请和释放内存,无需new和delete操作

(1)序列式容器:每个元素都有固定位置——取决于插入时机和地点,和元素值无关,vector、deque、list

vector(单向动态数组):将元素置于一个动态数组中加以管理,可以随机存取元素(用索引直接存取),数组尾部添加或移除元素非常快速。但是在中部或头部安插元素比较费时;
deque(双向动态数组):是“double-ended queue”的缩写,可以随机存取元素(用索引直接存取),数组头部和尾部添加或移除元素都非常快速。但是在中部或头部安插元素比较费时;
list(双向链表):不提供随机存取(按顺序走到需存取的元素),在任何位置上执行插入或删除动作都非常迅速,内部只需调整一下指针;

(2)关联式容器:元素位置取决于特定的排序准则,和插入顺序无关,set、multiset、map、multimap

set/multiset:set内的相同数值的元素只能出现一次,multisets内可包含多个数值相同的元素,内部的元素依据其值自动排序,由二叉树实现,便于查找;
map/multimap:map的元素是成对的键值/实值,map内的相同数值的元素只能出现一次,multimaps内可包含多个数值相同的元素,内部的元素依据其值自动排序,由二叉树实现,便于查找;

迭代器

Iterator(迭代器):用于提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。或者这样说可能更容易理解:Iterator模式是运用于聚合对象的一种模式,通过运用该模式,使得我们可以在不知道对象内部表示的情况下,按照一定顺序(由iterator提供的方法)访问聚合对象中的各个元素

迭代器的作用:能够让迭代器与算法不干扰的相互发展,最后又能无间隙的粘合起来,重载了*,++,==,!=,=运算符。用以操作复杂的数据结构,容器提供迭代器,算法使用迭代器;常见的一些迭代器类型:iterator、const_iterator、reverse_iterator和const_reverse_iterator

算法

算法部分主要由头文件<algorithm>,<numeric>和<functional>组成。
<algorithm>是所有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。
<numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。
<functional>中则定义了一些模板类,用以声明函数对象。

STL中算法大致分为四类:
非可变序列算法:指不直接修改其所操作的容器内容的算法。
可变序列算法:指可以修改它们所操作的容器内容的算法。
排序算法:对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。
数值算法:对容器内容进行数值计算。

适配器

标准库提供了三种顺序容器适配器:queue(FIFO队列)、priority_queue(优先级队列)、stack(栈)
要使用适配器,需要加入一下头文件:

#include <stack>       //stack
#include <queue>       //queue、priority_queue
queue

默认顺序容器:deque
可用顺序容器:list、deque
说明:FIFO队列,基础容器必须提供push_front()运算

priority_queue

默认顺序容器:vector
可用顺序容器:vector、deque
说明:优先级队列,基础容器必须提供随机访问功能

stack

默认顺序容器:deque
可用顺序容器:vector、list、deque
说明:栈

定义适配器

1、初始化:stack<int> stk(dep);
2、覆盖默认容器类型:stack<int,vector<int> > stk;

范例函数
queue/priority_queue范例函数:
queue<int> q; 
priority_queue<int> q;

两者通用函数:

q.empty();  //判断队列是否为空
q.size();   //返回队列长度
q.push(item);   //对于queue,在队尾压入一个新元素;对于priority_queue,在基于优先级的适当位置插入新元素

queue only:

q.front();  //返回队首元素的值,但不删除该元素
q.back();   //返回队尾元素的值,但不删除该元素

priority_queue only:

q.top();    //返回具有最高优先级的元素值,但不删除该元素
stack范例函数:
stack<int> s;
stack< int, vector<int> > s2;  //覆盖基础容器类型,使用vector实现stk
s.empty();  //判断stack是否为空,为空返回true,否则返回false
s.size();   //返回stack中元素的个数
s.pop();    //删除栈顶元素,但不返回其值
s.top();    //返回栈顶元素的值,但不删除此元素
s.push(item);   //在栈顶压入新元素item

常用容器用法

序列式容器:vector、deque、list:每个元素都有固定位置——取决于插入时机和地点,和元素值无关
关联式容器:set、multiset、map、multimap:元素位置取决于特定的排序准则,和插入顺序无关

vector(begin,end || pop和push只有back)

1、构造函数

vector<type> vec:声明一个元素类型为type的空vector
vector<type> vec(size):声明一个元素类型为type的vector,元素个数为size
vector<type> vec(size, value):声明一个元素类型为type的vector,元素个数为size,且值均为value
vector<type> obj(const vector&):复制构造函数
vector<type> obj(begin,end):复制[begin,end)区间数组的元素到vector中

2、增加函数

void push_back(const T& x):向量尾部增加一个元素X
iterator insert(iterator it,const T& x):向量中迭代器指向元素前增加一个元素x
iterator insert(iterator it,int n,const T& x):向量中迭代器指向元素前增加n个相同的元素x
iterator insert(iterator it,const_iterator first,const_iterator last):
向量中迭代器指向元素前插入另一个相同类型向量的[first,last)间的数据

3、删除函数

iterator erase(iterator it):删除向量中迭代器指向元素
iterator erase(iterator first,iterator last):删除向量中[first,last)中元素
void pop_back():删除向量中最后一个元素
void clear():清空向量中所有元素

4、遍历函数

reference at(int pos):返回pos位置元素的引用
reference front():返回首元素的引用
reference back():返回尾元素的引用
iterator begin():返回向量头指针,指向第一个元素
iterator end():返回向量尾指针,指向向量最后一个元素的下一个位置
reverse_iterator rbegin():反向迭代器,指向最后一个元素
reverse_iterator rend():反向迭代器,指向第一个元素之前的位置

5、判断函数

bool empty() const:判断向量是否为空,若为空,则向量中无元素

6、大小函数

int size() const:返回向量中元素的个数
int capacity() const:返回当前向量张红所能容纳的最大元素值
int max_size() const:返回最大可允许的vector元素数量值

7、其他函数

void swap(vector&):交换两个同类型向量的数据
void assign(int n,const T& x):设置向量中第n个元素的值为x
void assign(const_iterator first,const_iterator last):向量中[first,last)中元素设置成当前向量元素
补,待换位子
reverse(obj.begin(),obj.end()); 从头到尾进行反转

sort(obj.begin(),obj.end()); 从头到尾进行排序,第三个参数不写,默认升序
sort(obj.begin(),obj.end(),compare);写参数时可按下方格式创建bool值
bool compare(int a,int b) 
 { 
    return a< b; //升序排列,如果改为return a>b,则为降序
 } 

8、看着清楚

1.push_back 在数组的最后添加一个数据
2.pop_back 去掉数组的最后一个数据
3.erase 删除指针指向的数据项
4.clear 清空当前的vector
5.empty 判断vector是否为空

6.at 得到编号位置的数据
7.begin 得到数组头的指针
8.end 得到数组的最后一个单元+1的指针
9.front 得到数组头的引用
10.back 得到数组的最后一个单元的引用
11.rbegin 将vector反转后的开始指针返回(其实就是原来的end-1)
 12.rend 将vector反转构的结束指针返回(其实就是原来的begin-1)

13.max_size 得到vector最大可以是多大
14.capacity 当前vector分配的大小
15.size 当前使用数据的大小
16.resize 改变当前使用数据的大小,如果它比当前使用的大,者填充默认值
17.reserve 改变当前vecotr所分配空间的大小

18.swap 与另一个vector交换数据
访问方式

1、vector可以直接访问(类似于数组的[ ]还有at( )方式和指针方式)
2、借由迭代器进行间接访问

vector<int>::iterator it;//声明一个迭代器,来访问vector容器,作用:遍历或者指向vector容器的元素 
for(it=vec.begin();it!=vec.end();it++)
{
    cout<<*it<<" ";
}
deque(front,back || pop和push有front和back)

虽然deque也提供Iterator,但它的迭代器并不是普通指针,其复杂度和vector不可同日而语。因此,我们应尽可能选择使用vector而非deque。对deque进行的排序操作,为了最高效率,可将deque先完整复制到一个vector身上,将vector排序后(利用STL的sort算法),再复制回deque。

1、构造函数

#include<deque>  // 头文件
deque<type> deq;  // 声明一个元素类型为type的双端队列deque
deque<type> deq(size);  // 声明一个类型为type、含有size个默认值初始化元素的的双端队列deque
deque<type> deq(size, value);  // 声明一个元素类型为type、含有size个    value元素的双端队列deque
deque<type> deq(mydeque);  // 复制构造函数
deque<type> deq(first,last);  // 复制[first,last)区间数组的元素到deque中

2、

deq[ ]:用来访问双向队列中单个的元素。
deq.front():返回第一个元素的引用。
deq.back():返回最后一个元素的引用。
deq.push_front(x):把元素x插入到双向队列的头部。
deq.pop_front():弹出双向队列的第一个元素。
deq.push_back(x):把元素x插入到双向队列的尾部。
deq.pop_back():弹出双向队列的最后一个元素。

3、deque的一些特点

1.支持随机访问,即支持[ ]以及at(),但是性能没有vector好。
2.可以在内部进行插入和删除操作,但性能不及list。
3.deque两端都能够快速插入和删除元素,而vector只能在尾端进行。
4.deque的元素存取和迭代器操作会稍微慢一些,因为deque的内部结构会多一个间接过程。
5.deque迭代器是特殊的智能指针,而不是一般指针,它需要在不同的区块之间跳转。
6.deque可以包含更多的元素,其max_size可能更大,因为不止使用一块内存。
7.deque不支持对容量和内存分配时机的控制。
8.在除了首尾两端的其他地方插入和删除元素,都将会导致指向deque元素的任何pointers、references、iterators失效。不过,deque的内存重分配优于vector,因为其内部结构显示不需要复制所有元素。
9.deque的内存区块不再被使用时,会被释放,deque的内存大小是可缩减的。不过,是不是这么做以及怎么做由实际操作版本定义。
10.deque不提供容量操作:capacity()和reverse(),但是vector可以。

访问方式

1、deque同vector可以直接访问(类似于数组的[ ]还有at( )方式和指针方式)
2、借由迭代器进行间接访问

deque<int>::iterator it;//声明一个迭代器,来访问deque容器,作用:遍历或者指向deque容器的元素 
deque<int>::iterator it;
for (it = deq.begin(); it != deq.end(); it++) 
{
    cout << *it << ' ';
}
list()

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

1、构造函数

list<type> lst;  // 声明一个元素类型为type的空list
list<type> lst(size);  // 声明一个类型为type、含有size个默认值初始化元素的的list
list<type> lst(size, value);  //声明一个元素类型为type、含有size个value元素的list
list<type> lst(mylist);  // 复制构造函数
list<type> lst(begin,end);  //复制[begin,end)区间数组的元素到deque中

2、常用函数

lst.assign() 给list赋值
lst.back() 返回最后一个元素
lst.begin() 返回指向第一个元素的迭代器
lst.clear() 删除所有元素
lst.empty() 如果list是空的则返回true
lst.end() 返回末尾的迭代器
lst.erase() 删除一个元素
lst.front() 返回第一个元素
lst.get_allocator() 返回list的配置器
lst.insert() 插入一个元素到list中
lst.max_size() 返回list能容纳的最大元素数量
lst.merge() 合并两个list

lst.pop_back() 删除最后一个元素
lst.pop_front() 删除第一个元素
lst.push_back() 在list的末尾添加一个元素
lst.push_front() 在list的头部添加一个元素

lst.rbegin() 返回指向第一个元素的逆向迭代器
lst.remove() 从list删除元素
lst.remove_if() 按指定条件删除元素
lst.rend() 指向list末尾的逆向迭代器
lst.resize() 改变list的大小
lst.reverse() 把list的元素倒转
lst.size() 返回list中的元素个数
lst.sort() 给list排序
lst.splice() 合并两个list
lst.swap() 交换两个list
lst.unique() 删除list中相邻重复的元素

lst.insert(++list1.begin(), 3, 9);在第一个元素后插入3个9

map/multimap
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容