C++ STL总结

C + + C++ C++ S T L STL STL总结

一、 S T L STL STL概述

1.1 S T L STL STL简介

  1. 定义
    • S T L STL STL S t a n d a r d T e m p l a t e L i b r a r y Standard Template Library StandardTemplateLibrary),即标准模板库,是一个具有工业强度的,高效的C++程序库。该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法。
  2. 特点
    • S T L STL STL的一个重要特点是数据结构和算法的分离。尽管这是个简单的概念,但这种分离确实使得 S T L STL STL变得非常通用。例如,由于 S T L STL STL s o r t sort sort()函数是完全通用的,你可以用它来操作几乎任何数据集合,包括链表,容器和数组;
    • S T L STL STL另一个重要特性是它不是面向对象的。为了具有足够通用性, S T L STL STL主要依赖于模板而不是封装,继承和虚函数(多态性)—— O O P OOP OOP的三个要素。你在 S T L STL STL中找不到任何明显的类继承关系。这好像是一种倒退,但这正好是使得 S T L STL STL的组件具有广泛通用性的底层特征。另外,由于 S T L STL STL是基于模板,内联函数的使用使得生成的代码短小高效;
  3. 分类
    • S T L STL STL的代码从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器)。几乎所有的代码都采用了模板类模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。

1.2 S T L STL STL历史

A l e x a n d e r   S t e p a n o v Alexander\ Stepanov Alexander Stepanov(后被誉为 S T L STL STL标准模板库之父,后简称 S t e p a n o v Stepanov Stepanov),1950 年出生与前苏联的莫斯科,他曾在莫斯科大学研究数学,此后一直致力于计算机语言和泛型库研究。

在 20 世纪 70 年代, S t e p a n o v Stepanov Stepanov开始考虑,在保证效率的前提下,是否能将算法从诸多具体应用之中抽象出来?为了验证自己的思想,他和纽约州立大学教授 D e e p a k   K a p u r Deepak\ Kapur Deepak Kapur以及伦塞里尔技术学院教授 D a v i d   M u s s e r David\ Musser David Musser共同开发了一种叫做 T e c t o n Tecton Tecton的语言,尽管这次尝试没有取得实用性的成果,但却给了 S t e p a n o v Stepanov Stepanov很大的启示。

在随后的几年中,他又和 D a v i d   M u s s e r David\ Musser David Musser等人先后用 S c h e m a Schema Schema语言(一种 L i s p Lisp Lisp语言的变种)和 Ada 语言建立了一些大型程序库。 S t e p a n o v Stepanov Stepanov逐渐意识到,在当时的面向对象程序设计思想中存在一些问题,比如抽象数据类型概念所存在的缺陷,他希望通过对软件领域中各组成部分的分类,逐渐形成一种软件设计的概念性框架。

1987 年,在贝尔实验室工作的 S t e p a n o v Stepanov Stepanov开始首次采用 C + + C++ C++语言进行泛型软件库的研究。由于当时的 C + + C++ C++语言还没有引入模板的编程技术,泛型库只能是通过 C + + C++ C++的继承机制来开发,代码表达起来非常笨拙。

但尽管如此, S t e p a n o v Stepanov Stepanov还是开发出了一个庞大的算法库。与此同时,在与 A n d r e w   K o e n i g Andrew\ Koenig Andrew Koenig(前 I S O ISO ISO C + + C++ C++ 标准化委员会主席)和 B j a r n e   S t r o u s t r u p Bjarne\ Stroustrup Bjarne Stroustrup C + + C++ C++语言的创始人)等顶级大师们的共事过程中, S t e p a n o v Stepanov Stepanov开始注意到 C / C + + C/C++ C/C++语言在实现其泛型思想方面所具有的潜在优势。

就拿 C / C + + C/C++ C/C++中的指针而言,它的灵活与高效运用使后来的 S T L STL STL在实现泛型化的同时更是保持了高效率。另外,在 S T L STL STL中占据极其重要地位的迭代器概念便是源自于 C / C + + C/C++ C/C++中原生指针的一般化推广。

1988 年, S t e p a n o v Stepanov Stepanov开始进入惠普的 P a l o   A l t o Palo\ Alto Palo Alto实验室工作,在随后的 4 年中,他从事的是有关磁盘驱动器方面的工作。直到 1992 年,由于参加并主持了实验室主任 B i l l   W o r l e y Bill\ Worley Bill Worley所建立的一个有关算法的研究项目,才使他重新回到了泛型化算法的研究工作上来。

项目自建立之后,参与者从最初的 8 人逐渐减少,最后只剩下 S t e p a n o v Stepanov Stepanov M e n g   L e e Meng\ Lee Meng Lee两个人。经过长时间的努力,最终完成了一个包含有大量数据结构和算法部件的庞大运行库( H P HP HP 版本的 C + + C++ C++ S T L STL STL),这便是现在 S T L STL STL的雏形。

1993 年,当时在贝尔实验室的 A n d r e w   K o e n i g Andrew\ Koenig Andrew Koenig看到了 S t e p a n o v Stepanov Stepanov的研究成果,在他的鼓励与帮助下, S t e p a n o v Stepanov Stepanov于 1993 年 9 月在圣何塞为 A N S I / I S O ANSI/ISO ANSI/ISO C + + C++ C++标准委员会做了一个题为 “ T h e S c i e n c e o f C + + P r o g r a m m i n g ” “The Science of C++ Programming” TheScienceofC++Programming的演讲,向委员们讲述了其观念。然后又于 1994 年 3 月,在圣迭戈会议上向委员会提交了一份建议书,以期将 S T L STL STL通用库纳入 C + + C++ C++标准。

尽管这一建议十分庞大,以至于降低了被通过的可能性,但其所包含的新思想吸引了许多人的注意力。随后在众人的帮助之下,包括 B j a m e   S t r o u s t r u p Bjame\ Stroustrup Bjame Stroustrup在内, S t e p a n o v Stepanov Stepanov又对 S T L STL STL进行了改进,同时加入了一个封装内存模式信息的抽象模块,也就是现在 S T L STL STL中的 a l l o c a t o r allocator allocator(内存分配器),它使 S T L STL STL的大部分实现都可以独立于具体的内存模式,从而独立于具体平台。

最终在 1994 年的滑铁卢会议上,委员们通过了提案,决定将 S T L STL STL正式纳入 C + + C++ C++标准化进程之中,随后 S T L STL STL便被放进了会议的工作文件中。自此, S T L STL STL终于成为 C + + C++ C++家族中的重要一员。

此后,随者 C + + C++ C++标准的不断改进, S T L STL STL也在不断地做着相应的演化。直至 1998 年, A N S I / I S O ANSI/ISO ANSI/ISO C + + C++ C++ 标准正式定案, S T L STL STL 始终是 C + + C++ C++ 标准库不可或缺的重要组成部分。

二、 S T L STL STL基本框架

2.1 S T L STL STL组件

组件描述
容器(Containers)各种数据结构,如 v e c t o r , l i s t , d e q u e , s e t , m a p vector,list,deque,set,map vectorlistdequesetmap等用来存放数据。从实现角度来看, S T L STL STL容器是一种class template。
算法(Algorithms)算法作用于容器。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。
迭代器(iterators)扮演容器与算法之间的胶合剂,是所谓的“泛型指针”,共有5种类型,以及其它衍生变化。
仿函数(Function object)行为类似函数,可以作为算法的某种策略。从实现角度来看,仿函数是一种重载了 o p e r a t o r operator operator()的 c l a s s class class c l a s s   t e m p l a t e class\ template class template。一般函数指针可视为狭义的仿函数。
适配器(Adapter)一种用来修饰容器或仿函数或迭代器接口的东西。如 S T L STL STL提供的 q u e u e queue queue s t a c k stack stack,虽然看似容器,其实只能算法一种容器配接器。
分配器(Allocator)负责空间配置与管理。从实现角度来看,配置器是一个实现动态空间配置、空间管理、空间释放的 c l a s s   t e m p l a t e class\ template class template

2.2 S T L STL STL头文件

  • C + + C++ C++标准中, S T L STL STL被组织为下面13个头文件: < a l g o r i t h m > 、 < d e q u e > 、 < f u n c t i o n a l > 、 < i t e r a t o r > 、 < v e c t o r > 、 < l i s t > 、 < m a p > 、 < m e m o r y > 、 < n u m e r i c > 、 < q u e u e > 、 < s e t > 、 < s t a c k > 和 < u t i l i t y > < algorithm>、< deque>、< functional>、< iterator>、< vector>、<l ist>、< map>、< memory>、< numeric>、< queue>、< set>、< stack>和<utility> <algorithm><deque><functional><iterator><vector><list><map><memory><numeric><queue><set><stack><utility>
  • 万能头文库< b i t s / s t d c + + . h bits/stdc++.h bits/stdc++.h>,只要用了这个头文件就不用写其他头文件。不过在国内 o j oj oj中, p o j poj poj h d u hdu hdu等不支持, P T A PTA PTA支持。

三、 S T L STL STL核心组件

3.1 容器

  1. 种类
    • 顺序容器:是一种各元素之间有顺序关系的线性表,是一种线性结构的可序群集。顺序性容器中的每个元素均有固定的位置,除非用删除或插入的操作改变这个位置。顺序容器的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定。顺序容器包括:vector(向量)、list(列表)、deque(队列)。
    • 关联容器:关联式容器是非线性的树结构,更准确的说是二叉树结构。各元素之间没有严格的物理上的顺序关系,也就是说元素在容器中并没有保存元素置入容器时的逻辑顺序。但是关联式容器提供了另一种根据元素特点排序的功能,这样迭代器就能根据元素的特点“顺序地”获取元素。元素是有序的集合,默认在插入的时候按升序排列。关联容器包括:map(集合)、set(映射)、multimap(多重集合)、 m u l t i s e t multiset multiset(多重映射)。
    • 容器适配器:本质上,适配器是使一种不同的行为类似于另一事物的行为的一种机制。容器适配器让一种已存在的容器类型采用另一种不同的抽象类型的工作方式实现。适配器是容器的接口,它本身不能直接保存元素,它保存元素的机制是调用另一种顺序容器去实现,即可以把适配器看作“它保存一个容器,这个容器再保存所有元素”。 S T L STL STL 中包含三种适配器:栈stack 、队列queue 和优先级队列priority_queue 。
  2. 主要容器
容器特性所在头文件
向量(vector)可以用常数时间访问和修改任意元素,在序列尾部进行插入和删除时,具有常数时间复杂度,对任意项的插入和删除就有的时间复杂度与到末尾的距离成正比,尤其对向量头的添加和删除的代价是惊人的高的< vector >
双端队列(deque)基本上与向量相同,唯一的不同是,其在序列头部插入和删除操作也具有常量时间复杂度< deque >
链表(list)对任意元素的访问与对两端的距离成正比,但对某个位置上插入和删除一个项的花费为常数时间。< list >
队列(queue)插入只可以在尾部进行,删除、检索和修改只允许从头部进行。按照先进先出的原则。< queue >
堆栈(stack)堆栈是项的有限序列,并满足序列中被删除、检索和修改的项只能是最近插入序列的项。即按照后进先出的原则< stack >
集合(set)由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序,具有快速查找的功能。但是它是以牺牲插入删除操作的效率为代价的< set >
多重集合(multiset)和集合基本相同,但可以支持重复元素具有快速查找能力< set >
映射map由{键,值}对组成的集合,以某种作用于键对上的谓词排列。具有快速查找能力< map >
多重集合(multimap)比起映射,一个键可以对应多了值。具有快速查找能力< map >

3.2 算法

  1. 介绍
    • S T L STL STL提供了大约100个实现算法的模版函数。只要我们熟悉了 S T L STL STL之后,许多代码可以被大大的化简,只需要通过调用一两个算法模板,就可以完成所需要的功能并大大地提升效率。
  2. 头文件
    • < algorithm >是所有 S T L STL STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。
    • < numeric >体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。
    • < functional >中则定义了一些模板类,用以声明函数对象。
  3. 大致分类:
    • 非可变序列算法:指不直接修改其所操作的容器内容的算法。
    • 可变序列算法:指可以修改它们所操作的容器内容的算法。
    • 排序算法:对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。
    • 数值算法:对容器内容进行数值计算。
  4. 细致分类
    • 查找算法(13个)
    • 排序和通用算法(14个)
    • 删除和替换算法(15个)
    • 算术算法(4个)
    • 生成和异变算法(6个)
    • 关系算法(8个)
    • 集合算法(4个)
    • 堆算法(4个)

3.3迭代器

  1. 定义
    • I t e r a t o r Iterator Iterator(迭代器)模式又称 C u r s o r Cursor Cursor(游标)模式,用于提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。可以把迭代器看作一个指向容器中元素的普通指针,可以如递增一个指针那样递增迭代器,使其依次指向容器中每一个后继的元素。迭代器是 S T L STL STL中的一个关键部分,因为它将算法和容器连接在一起。
  2. 作用
    • 能够让迭代器与算法不干扰的相互发展,最后又能无间隙的粘合起来,重载了 ∗ , + + , = = , ! = , = *,++,==,!=,= 运算符。用以操作复杂的数据结构,容器提供迭代器,算法使用迭代器;常见的一些迭代器类型:iterator、const_iterator、reverse_iterator和const_reverse_iterator。
  3. 头文件
    • < utility >:是一个很小的头文件,它包括了贯穿使用在 S T L STL STL中的几个模版的声明;
    • < iterator >:提供了迭代器使用的许多方法;
    • < memory >:它以不同寻常的方式为容器中的元素分配存储空间,同时也为某些算法执行期间产生的临时对象提供机制;< memory >中的主要部分是模板类allocator,它负责产生所有容器中的默认分配器。
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值