首页 > 其他分享 >STL总结

STL总结

时间:2023-10-10 10:02:08浏览次数:38  
标签:总结 容器 迭代 STL 元素 queue 队列 算法


    STL(Standard Template Library)里有很多组成部分,但是主要有三个,容器、迭代器和算法
    容器用来管理某个特定对象的集合。每一种容器都有自己的优点和缺点,在项目中根据不同的需求,使用不同的容器。容器可以是数组、链表或者类字典。
    迭代器用于遍历对象集合的元素。这些集合可以是容器或容器的子集。每一个容器类都提供了它自己的迭代器类型。
    算法用来处理的元素的集合。例如,可以进行搜索、排序等操作。

    STL的数据和操作是分离的。数据存储在容器里,使用算法进行操作。迭代器是这两者之间的粘合剂,让算法与容器可以进行交互。

STL数据和算法是分离的而不是结合。STL是泛型编程的一个很好的例子。容器和算法分别是任意类型和类的泛型。STL提供了更通用的组件。还可以通过使用适配器和仿函数来达到特殊要求。


一、容器

1、主要可以分为三大类 :
    序列容器是有序集合,其中的每个元素都有特定位置。这个位置取决于插入的时间和地点,但是它跟元素的值无关。STL包含5个预定义的序列容器类:array、vector、deque、list和forward_list。
    关联容器是把元素的值按照某种规则排好顺序的集合。STL包含4个预定义的关联容器类:set、multiset、map和multimap。
    无序(关联)容器是无序集合。主要关注一个元素是否在集合中。不论是插入的顺序还是插入元素的值对元素的位置都没有任何影响。STL包含4个预定义的无序容器类:unordered_set、unordered_multiset、unordered_map和unordered_multimap。

    序列容器通常是数组或链表的实现 。
    关联容器通常是二叉树的实现 。
    无序容器通常是哈希表的实现。

2、各种容器的特点:

(1)vector
    内部数据结构:数组。
    随机访问每个元素,所需要的时间为常量。
    在末尾增加或删除元素所需时间与元素数目无关,在中间或开头增加或删除元素所需时间随元素数目呈线性变化。
可动态增加或减少元素,内存管理自动完成,但程序员可以使用reserve()成员函数来管理内存。
    vector的迭代器在内存重新分配时将失效(它所指向的元素在该操作的前后不再相同)。当把超过capacity()-size()个元素插入vector中时,内存会重新分配,所有的迭代器都将失效;否则,指向当前元素以后的任何元素的迭代器都将失效。当删除元素时,指向被删除元素以后的任何元素的迭代器都将失效。


(2)deque
    内部数据结构:数组。
    随机访问每个元素,所需要的时间为常量。
在开头和末尾增加元素所需时间与元素数目无关,在中间增加或删除元素所需时间随元素数目呈线性变化。
可动态增加或减少元素,内存管理自动完成,不提供用于内存管理的成员函数。
    除开头结尾外,增加任何元素都将使deque的迭代器失效。在deque的中间删除元素将使迭代器失效。在deque的头或尾删除元素时,只有指向该元素的迭代器失效。


(3)list
    内部数据结构:双向环状链表。
    不能随机访问一个元素。
    可双向遍历。
    在开头、末尾和中间任何地方增加或删除元素所需时间都为常量。可动态增加或减少元素,内存管理自动完成。
    增加任何元素都不会使迭代器失效。删除元素时,除了指向当前被删除元素的迭代器外,其它迭代器都不会失效。


(4)forward_list

    内部数据结构:单向链表。

    不可双向遍历,只能从前到后地遍历。

    它的特性同list相似。


(5)set
    键和值相等。键唯一。
    元素默认按升序排列。
    如果迭代器所指向的元素被删除,则该迭代器失效。其它任何增加、删除元素的操作都不会使迭代器失效。


(6)multiset
    键可以不唯一。
    其它特点与set相同。


(7)map
    键唯一。

    元素默认按键的升序排列。

    如果迭代器所指向的元素被删除,则该迭代器失效。其它任何增加、删除元素的操作都不会使迭代器失效。


(8)multimap
    键可以不唯一。
    其它特点与map相同。

STL总结_删除元素

3、容器的选择:

1)除非你有更好的选择,否则应该使用vector。
2)如果你的程序有很多小的元素,且空间的额外开销很重要,则不要使用list或者forward_list。
3)如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector。
4)如果你需要大量的插入和删除,而不关心随即存取,则应使用list。
5)如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。
6)如果你要存储一个数据字典,并要求方便地根据key找value,那么map是较好的选择;如果key对应多个value,应选择multimap。
7)如果你要查找一个元素是否在某集合内存中,则使用set存储这个集合比较好。


二、容器适配器
    容器适配器提供顺序容器的特殊接口。

1、各种适配器的特点:

(1)stack 堆栈适配器(LIFO)

    stack 模板类的定义在<stack>头文件中。
    stack 模板类需要两个模板参数,一个是元素类型,一个容器类型,但只有元素类型是必要的,在不指定容器类型时,默认的容器类型为deque。
    定义stack 对象的示例代码如下:
    stack<int> s1;
    stack<string> s2;
    stack 的基本操作有:
    入栈,如例:s.push(x);
    出栈,如例:s.pop();注意,出栈操作只是删除栈顶元素,并不返回该元素。
    访问栈顶,如例:s.top()
    判断栈空,如例:s.empty(),当栈空时,返回true。
    访问栈中的元素个数,如例:s.size()。


(2)queue 改写容器来提供队列(FIFO数据结构)

    queue 模板类的定义在<queue>头文件中。
    与stack 模板类很相似,queue 模板类也需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque 类型。
    定义queue 对象的示例代码如下:
    queue<int> q1;
    queue<double> q2;
    queue 的基本操作有:
    入队,如例:q.push(x); 将x 接到队列的末端。
    出队,如例:q.pop(); 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。
    访问队首元素,如例:q.front(),即最早被压入队列的元素。
    访问队尾元素,如例:q.back(),即最后被压入队列的元素。
    判断队列空,如例:q.empty(),当队列空时,返回true。
    访问队列中的元素个数,如例:q.size()。


(3)priority_queue 改写容器来提供优先级队列

    在<queue>头文件中,还定义了另一个非常有用的模板类priority_queue(优先队列)。

    优先队列与队列的差别在于优先队列不是按照入队的顺序出队,而是按照队列中元素的优先权顺序出队(默认为大者优先,也可以通过指定算子来指定自己的优先顺序)。
    priority_queue 模板类有三个模板参数,第一个是元素类型,第二个容器类型,第三个是比较算子。其中后两个都可以省略,默认容器为vector,默认算子为less,即小的往前排,大的往后排(出队时序列尾的元素出队)。
    定义priority_queue 对象的示例代码如下:
    priority_queue<int> q1;
    priority_queue< pair<int, int> > q2; // 注意在两个尖括号之间一定要留空格。
    priority_queue<int, vector<int>, greater<int> > q3; // 定义小的先出队。
    priority_queue 的基本操作与queue 相同。
    初学者在使用priority_queue 时,最困难的可能就是如何定义比较算子了。如果是基本数据类型,或已定义了比较运算符的类,可以直接用STL 的less 算子和greater算子——默认为使用less 算子,即小的往前排,大的先出队。如果要定义自己的比较算子,方法有多种,这里介绍其中的一种:重载比较运算符。优先队列试图将两个元素x 和y 代入比较运算符(对less 算子,调用x<y,对greater 算子,调用x>y),若结果为真,则x 排在y 前面,y 将先于x 出队,反之,则将y 排在x 前面,x 将先出队。


三、迭代器

    根据迭代器所支持的操作,一般分为下面5种:
    前向迭代器只能利用递增运算符进行前向迭代。像unordered_set、unordered_multiset、unordered_map和unordered_multimap这些容器都“至少”是用前向迭代器(某些情况下可以提供双向迭代器)。
    双向迭代器是可以用递增运算符向前迭代,或者用递减运算符向后迭代。像list、set、multiset、map和multimap的迭代器都是双向迭代器。
    随机访问迭代器具有双向迭代器的所有属性。此外,他们还可以进行随机访问。这种迭代器本身支持运算操作,可以改变偏移量,也可以利用关系运算符(< 和 >)比较迭代器。像vector、deque、array和string的迭代器都是这类迭代器。
   输入迭代器能够在迭代时读取或处理一些值。如Input stream iterators。
    输出迭代器能够在迭代时输出一些值。如Inserters、和output stream iterators。


四、算法

    STL提供了一些标准算法来处理集合元素。这些算法一般提供最基本的功能,如搜索、排序、复制、修改和数值处理。
    算法不是容器类的成员函数,而是全局函数。算法可以操作不同容器类型的元素,甚至可以操作用户自定义的容器类型。总之,既减少了代码量,又增强了性能。


五、迭代器适配器

    任何操作起来像迭代器的东西都可以当作迭代器。所以可以写出像迭代器的一些类但又执行不一样的操作。C++标准库提供的一些预定义的特殊迭代器,即迭代器适配器。一般分为四类:
    Insert iterators也称为inserters,用来将“赋值新值”操作转换为“安插新值”操作。通过这种迭代器,算法可以执行安插(insert)行为而非覆盖(overwrite)行为。所有Insert迭代器都隶属于Output迭代器类型,所以它只提供赋值(assign)新值的能力。通常算法会将数值赋值给目的迭代器,如copy()算法
    Stream iterators是一种迭代器配接器,可以把stream当成算法的原点和终点。更明确的说,一个istream迭代器可以用来从input stream中读元素,而一个ostream迭代器可以用来对output stream写入元素。Stream迭代器的一种特殊形式是所谓的stream缓冲区迭代器,用来对stream缓冲区进行直接读取和写入操作。
    Reverse iterators重新定义递增运算和递减运算,使其行为正好倒置。
    Move iterators很像一个底层迭代器(必须至少有一个InputIterator)。如果这个迭代器被当作输入迭代器来用,要注意的是,值的操作是移动而不是复制。


六、仿函数
    算法函数的参数不一定非要是函数。可以是行为类似函数的对象,称为函数对象,或仿函数。




标签:总结,容器,迭代,STL,元素,queue,队列,算法
From: https://blog.51cto.com/u_6526235/7788135

相关文章

  • 每日总结
    今日收获学会了vue+echarts试下数据可视化;软考的题目又看了好多,解决了好几个题型;背单词,但是没做英语题;明天预计继续背单词!!!!肯定有大型数据库的作业啦!--写作业去~继续学习软考题目;攻一下英语薄弱的题型;......
  • 10.9 日模拟赛总结
    看T1,\(n\le10^7\),鉴定为\(\mathcalO(n)\)做法,不会,睡觉。睡醒,一眼T1,一通操作打完代码,过样例,过不了大样例。写暴力找问题,调调调,过大样例,此时已过去2h。看T2,不会,乱推一个\(\mathcal(n^2)\)暴力润了。看T3,不会,打了个指数级暴力和特殊性质润了。看T4,不会,但有个性质图......
  • 每日总结10月9日
    今天的睡眠严重不足,中午还被迫去开了评选会,下午的课程里,数据库的连接确实让我两眼一黑,但还是通过了自己的努力成功的关联了数据库,至于程序那可真不是我能做出来的了,html看都看不懂,真的没办法 ......
  • 每日总结1009
    今天上了软件设计模式,课上讲了职责链模式和命令模式两种。然后是人机交互技术,课上老师介绍了div和css。今日代码:代码量:60行学习时间:6h(算上课)晚上背了单词,做了一些软考的选择题。......
  • 今日总结
    今天完成了企业ERP的页面绘制 ......
  • 2023.10.9——每日总结
    学习所花时间(包括上课):0h代码量(行):0行博客量(篇):1篇今天,上午学习,下午学习;我了解到的知识点:1.DIV+CSS;明日计划:学习......
  • .net 调用webservice 总结
    最近做一个项目,由于是在别人框架里开发app,导致了很多限制,其中一个就是不能直接引用webservice。我们都知道,调用webserivice最简单的方法就是在"引用" 那里点击右键,然后选择"引用web服务",再输入服务地址。确定后,会生成一个app.config里面就会自动生成了一些配置信息。现......
  • php常用总结
    1.PHP处理脚本解析(脚本不乱码)header('Conent-type:text/html;charset=utf-8');2.常用的系统函数2.1有关输出的函数:print和print_rprint()==类似于echo输出提供的内容,本质是一种结构(不是函数),返回1,可以不需要使用括号;print_r()==类似于var_dump,但是比var_dump简单,不会......
  • 深信服面经总结
     介绍项目的应用场景 和工业界应用的区别 学过什么数据结构和算法,刷过多少力扣题。 实现strcpy。看我写的慢给我打断了,问我是不是没写过。答曰是,把思路给它讲了下,并说明拷贝时可能出现的覆盖问题。 平时编程写的多吗?出了道题目。Vim上实现单词反转"Thisisagi......
  • 20231009 模拟赛总结
    模拟赛链接排名:\(\text{rank1}\)分数:\(100+100+70+20=290\)终于有一次模拟赛不掉分了。T1:最后一课/dist题目描述:在一个平面直角坐标系上,给定一条直线\(y=k\)和两个点\(P(x_1,y_1),Q(x_2,y_2)\),求经过水平线的两点的最短距离。(\(k,x_1,y_1,x_2,y_2\le5\times10^8\))思......