STL——算法简介
一、算法概观
以有限的步骤,解决逻辑或数学上的问题,这一专门科目我们称为算法。特定的算法往往搭配特定的数据结构,例如binary search tree(二叉搜索树)和 RB-tree 便是为了解决查找问题而发展出来的特殊数据结构。几乎可以说,特定的数据结构是为了实现某种特定的算法。本章所讨论的,是可施行于“无太多特殊条件限制”之空间中的某一段元素区间的算法。
1. 算法分析与复杂度表示O()
参见算法与数据结构相关书籍,如《算法设计与分析》《数据结构》等。
2. STL 算法总览
3. 质变算法mutating algorithms——会改变操作对象之值
所有的STL算法都作用在由迭代器[first, last) 所标示出来的区间上。所谓“质变算法”,是指运算过程中会更改区间内(迭代器所指)的元素内容。诸如拷贝(copy)、互换(swap)、替换(replace)、填写(fill)、删除(remove)、排列组合(permutation)、分割(partition)、随机重排(random shuffling)、排序(sort)等算法,都属此类。
4. 非质变算法nonmutating algorithms——不改变操作对象之值
所有的STL算法都作用在 由迭代器[first, last) 所标示出来的区间上。所谓“非质变算法”,是指运算过程中不会更改区间内(迭代器所指)的元素内容。诸如查找(find)、匹配(search)、计数(count)、巡访(for_each)、比较(equal,mismatch)、寻找极值(max,min)等算法,都属此类。
5. STL算法的一般形式
所有泛型算法的前两个参数都是一对迭代器,通常由first和last形成一个“前闭后开”区间[first, last)。根据行进特性,迭代器可分为5类,每一个STL算法的声明,都表现出它所需要的最低程度的迭代器类型。例如find() 需要一个InputIterator,这是它的最低要求,但它也可以接受更高类型的迭代器,如ForwardIterator,BidirectionalIterator或RandomAccessIterator,在 STL——迭代器与traits编程技法 文章中阐述的,不论ForwardIterator或BidirectionalIterator或RandomAccessIterator也都是一种InputIterator。但如果你交给find() 一个OutputIterator,会导致错误。
将无效的迭代器传给某个算法,虽然是一种错误,却不保证能够在编译时期就被捕捉出来,因为所谓“迭代器类型”并不是真实的型别,它们只是function template的一种型别参数(type parameters)。
许多STL算法不只支持一个版本。这一类算法的某个版本采用缺省运算行为,另一个版本提供额外参数,接受外界传入一个仿函数(functor),以便采用其他策略。
质变算法通常提供两个版本:一个是in-place(就地进行)版,就地改变其操作对象;另一个是copy(另地进行)版,将操作对象的内容复制一份副本,然后在副本上进行修改并返回该副本。copy版本总是以_copy作为函数名称后缀,如replace()和replace_copy()。并不是所有质变算法都有copy版,例如sort()就没有。如果我们希望以这类“无copy版本”之质变算法施行于某一段区间元素的副本身上,我们必须自行制作并传递那一份副本。
所有的数值(numeric)算法都实现于SGI<stl_numeric.h>之中,这是个内部文件,STL 规定用户必须包含的是上层<numeric>。其他STL算法都实现于SGI 的<stl_algo.h> 和 <stl_algobase.h>文件中,也都是内部文件;欲使用这些算法,必须先包含上层相关头文件<algorithm>。
二、算法的泛化过程 : "操作对象的型别+操作对象的标示法+区间目标的移动行为"三者的抽象化
如何将算法独立于其所处理的数据结构之外,关键在于,只要把操作对象的型别(使用模板template)加以抽象化,把操作对象的标示法(使用容器对应的迭代器来标示操作对象)和区间目标的移动行为(例如,一套STL容器的设计标准就规定要设计一个符合STL抽象算法操作行为的容器需要满足的条件,只有定义好了容器的设计标准,才有可能对“各种容器的不同操作行为”进行统一(也即抽象出)形成一个抽象行为,使得这个抽象行为在不同容器之上都能正常工作。而迭代器在这里便充当了容器和算法之间的胶着剂——通过迭代器(迭代器算法)取得容器中的对象,交予算法进行处理。)抽象化,整个算法也就在一个抽象层面上工作了。整个过程称为算法的泛型化,简称泛化。
三、算法实例
在《STL源码剖析》6.3节中,有针对各种算法,包括数值算法,基本算法,set相关算法,heap算法,以及其他多种常用算法的运用实例,详见书籍。
这里重点提一下下面几类算法:
(1)copy算法——强化效率无所不用其极
不论是对客户程序或是STL内部而言,copy()都是一个常常被调用的函数。由于copy进行的是复制操作,而复制操作不外乎运用assignment operator或copy constructor(copy算法用的是前者),但是某些元素型别拥有的是trivial(无价值的,微不足道的) assignment operator,因此,如果能够使用内存直接复制行为(例如C标准函数memove或memcpy),便能够节省大量时间。为此,SGI STL的copy算法用尽各种办法,包括函数重载、型别特性、偏特化等编程技巧,无所不用其极地加强效率。
注意,copy算法,需要特别注意区间重叠的情况:
如图6-3所示:
如果输入区间和输出区间完全没有重叠,当然毫无问题,否则便需特别注意.为什么图6-3第二种情况(可能)会产生错误?从源代码可得知,copy算法是一一进行元素的赋值操作,如果输出区间的起点位于输入区间内,copy算法便(可能)会在输入区间的(某些)元素尚未被复制之前,就覆盖其值,导致错误哦结果.在这里我一再使用"可能"这个字眼,是因为,如果copy算法根据其所接收的迭代器的特性决定调用memmove()来执行任务,就不会造成上述错误,因为memmove()会先将整个输入区间的内容复制下来,没有被覆盖的危险.
(2)sort算法
STL所提供的各式各样算法中,sort()是最复杂最庞大的一个。这个算法接受两个RandomAccessIterators(随机存取迭代器),然后将区间内的所有元素以渐增方式由小到大重新排列。第二个版本则允许用户指定一个仿函数,作为排序标准。STL的所有关系型容器都拥有自动排序功能(底层结构采用RB-tree),所以不需要用到这个sort算法。至于序列式容器中的stack、queue和priority-queue都有特别的出入口,不允许用户对元素排序。剩下vector、deque和list,前两者的迭代器属于RandomAccessIterator,适合使用sort算法,list的迭代器则属于BidirectionalIterators,不在STL标准之列的slist,其迭代器更属于RorwardIterator,都不适合使用sort算法。
STL 的sort算法,数据量大时采用Quick Sort,分段递归排序。一旦分段后的数据量小于某个门槛,为避免Quick Sort的递归调用带来过大的额外负荷,就改用Insertion Sort。如果递归层次过深,还会改用Heap Sort。 关于Quick Sort和Insertion Sort算法,以及排序相关的其他算法,参考相关算法书籍。
STL——算法简介的更多相关文章
- C++11 STL算法简介
STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库.它被容纳于C++标准程序库(C++ Standard Library)中,是ANS ...
- STL所有算法简介 (转) http://www.cnblogs.com/yuehui/archive/2012/06/19/2554300.html
STL所有算法简介 STL中的所有算法(70个) 参考自:http://www.cppblog.com/mzty/archive/2007/03/14/19819.htmlhttp://hi.baid ...
- STL的简介
Standard Template Library,(标准模板库)<来自百度百科的整理> ————可复用性(reusability) STL是基于模板,内联函数的使用使得生成的代码短小高效 ...
- webrtc 的回声抵消(aec、aecm)算法简介(转)
webrtc 的回声抵消(aec.aecm)算法简介 webrtc 的回声抵消(aec.aecm)算法主要包括以下几个重要模块:1.回声时延估计 2.NLMS(归一化最小均方自适应算法) ...
- STL算法
STL算法部分主要由头文 件<algorithm>,<numeric>,<functional>组成.要使用 STL中的算法函数必须包含头文件<algorit ...
- 【STL源码学习】STL算法学习之四
排序算法是STL算法中相当常用的一个类别,包括部分排序和全部排序算法,依据效率和应用场景进行选择. 明细: sort 函数原型: template <class RandomAccessIter ...
- 【STL源码学习】STL算法学习之三
第一章:前言 数量不多,用到的时候会很爽. 第二章:明细 STL算法中的又一个分类:分割:将已有元素按照既定规则分割成两部分. is_partitioned 函数原型: template <c ...
- 【STL源码学习】STL算法学习之二
第一章:前言 学习笔记,记录学习STL算法的一些个人所得,在以后想用的时候可以快速拾起. 第二章:明细 copy 函数原型: template <class InputIterator, cla ...
- 【转】三十分钟学会STL算法
转载自: http://net.pku.edu.cn/~yhf/UsingSTL.htm 这是本小人书.原名是<using stl>,不知道是谁写的.不过我倒觉得很有趣,所以化了两个晚上把 ...
随机推荐
- 去掉WIN7 桌面图标的小箭头
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons" ...
- python爬虫数据-下载图片经典案例
'''Urllib 模块提供了读取web页面数据的接口,我们可以像读取本地文件一样读取www和ftp上的数据.首先,我们定义了一个getHtml()函数: urllib.urlopen()方法用于打开 ...
- 2016年第七届蓝桥杯C/C++B组省赛题目解析
题目1:煤球数目 有一堆煤球,堆成三角棱锥形.具体:第一层放1个,第二层3个(排列成三角形),第三层6个(排列成三角形),第四层10个(排列成三角形),....如果一共有100层,共有多少个煤球?请填 ...
- mysql -- 远程访问mysql的解决方案
1.改表法 可能是你的帐号不允许从远程登陆,只能在localhost.这个时候只要在localhost的那台电脑,登入mysql后,更改 "mysql" 数据库里的 "u ...
- C# 实现数字字符串左补齐0的两种方法
); MessageBox.Show(sss); return; 代码如上,自动补齐前面的0
- CSS3和jQuery实现的自定义美化Checkbox和Radiobox
现在经常可以在网络上看到一些非常奇特的表单元素,例如Checkbox复选框和Radiobox单选框,浏览器默认的样式确实是太丑了,而且更让人蛋疼的是各个浏览器的样式还不统一,考虑到现在越来越多的用户使 ...
- Godray
软管的这个有点蛋疼..应该是我材质没弄好 最后发现不是材质,是法线不正确,调整后
- 地形系统lod
参考其他引擎,地形有近到远进行越来越深的lod,基本完成 下面是u3d的,觉得原理应该是一样的
- C++ 著名程序库 概览
本文转载自: http://ace.acejoy.com/thread-3777-1-1.html 1.C++各大有名库的介绍--C++标准库 2.C++各大有名库的介绍--准标准库B ...
- SharePoint 2013 处理Promoted Links类型的List下的Tiles View的默认Webpart展示方式
问题: 为了去掉Photo Gallery的水平滚动效果,更改为根据内容进行自适应宽度多行显示效果 Promoter link --> photo gallery Not horizontal ...