
STL学习
文章平均质量分 81
本专栏主要记录《STL源码剖析》的学习过程
大明__
技术爱好者,通过分享进行学习实践;涉及领域主要包括:C/C++,算法与数据结构,网络安全,数据安全,设计模式,系统架构,数据库,多线程高并发等
展开
-
STL算法之sort
STL所提供的各式各样算法中,sort()是最复杂最庞大的一个。这个算法接受两个RandomAccessIterators(随机存取迭代器),然后将区间内的所有元素以渐增方式由小到大重新排列。还有一个版本则是允许用户指定一个仿函数代替operator原创 2024-12-04 23:54:31 · 1388 阅读 · 0 评论 -
STL之适配器(adapters)_下
请注意,源代码清楚地告诉我们,只要客户端定义一个istream iterator并绑定到某个istream object,程序便立刻停在istream_iterator::read()函数,等待输入,这不是我们所预期的行为,因此,请在绝对必要的时候才定义所需要的istream iterator- -这其实是C++程序员在任何时候都应该遵循的守则,但是很多人都忽略了。注意,本节的两个适配器并未纳入STL标准,SGI STL的私产品,但是颇有钻研价值,我们可以从中学习如何开发适合自己的,更复杂的适配器。原创 2024-12-08 22:11:25 · 611 阅读 · 0 评论 -
STL之适配器(adapters)_上
这样的迭代器包括专司尾端插入操作的back_insert_iterator,专司头端插入操作的front_insert_iterator,以及可以从任意位置执行插入操作的insert_iterator.由于这三个iterator adapters的使用接口不是十分直观,给一般用户带来困扰,因此,STL更提供三个相应函数:back_inserter(),front_inserter(),inserter();所谓对迭代器的修饰,只是一种观念上的改变(复制操作变为插入操作,前进变后退,绑定到特殊装置上等)。原创 2024-12-08 00:10:45 · 860 阅读 · 0 评论 -
STL仿函数
仿函数functors另名函数对象functions objects。在之前的算法介绍中,我们已经用到了仿函数。此章,我们对仿函数做一个更详细的介绍。原创 2024-12-06 23:24:42 · 920 阅读 · 0 评论 -
STL算法之merge sort
在中,我们对inplace_merge进行了简要的描述,但是对里面的细节描述的不是很清晰;本章进行更细致的拆解;同时merge将使用merge sort作为实现算法的主要手段。原创 2024-12-05 22:27:03 · 990 阅读 · 0 评论 -
STL算法之其它算法_下
这个算法将[first,last)的元素次序随机排列。也就说,在N!中可能的元素排列中随机选出一种,此处N为last-first。N个元素的序列,其排列方式为N!中,random_shuffle会产生一个均匀分布,因此任何一个排列被选中的几率为1/N!。这很重要(稍后看源码,事实上依赖于随机数是否真随机),因为有不少算法可能会依赖排列的随机性。其算法实现过程,基本也是依次对每个元素进行随机的替换,以实现随机排列的功能。原创 2024-12-03 23:37:07 · 801 阅读 · 0 评论 -
STL算法之其它算法_中
而其后一个排列组合是cab。实际做法简述如下,从最尾端开始往前寻找两个相邻元素,令第一个元素为*i,第二个元素为*ii,且满足*i>*ii.找到这样一组相邻元素后,再从尾端开始往前检验,找到第一个小于*i的元素,令为*j,将i,j元素对调,再将ii之后的所有元素颠倒排序。首先,从尾端往前寻找两个相邻的元素,令第一个元素为*i,第二个元素为*ii,且满足*i原创 2024-12-02 22:23:46 · 830 阅读 · 0 评论 -
STL算法之其他算法_上
定义于SGI内的所有算法,除了相关算法之前已经介绍过,其余安排在该文中。其中有很单纯的循环遍历,也有很复杂的快速排序。运作相对单纯者,在第一小节中,其他相对比较复杂的算法,每个算法各一小节。原创 2024-12-01 23:40:29 · 1116 阅读 · 0 评论 -
STL算法之set相关算法
STL一共提供了四种与set(集合)相关的算法,分别是并集(union)、交集(intersection)、差集(difference)、对称差集(symmetric difference)。所谓set,可细分为数学上定义的和STL的定义两种,数学上的set允许元素重复而未经排序,例如{1,1,4,6,3},STL的定义(也就是容器)则要求元素不得重复,并且经过排序,例如{1,3,4,6}。本节的四个算法所接受的set,必须是有序区间(sorted range),元素值可重复出现。原创 2024-11-30 23:12:36 · 813 阅读 · 0 评论 -
STL基本算法之copy与copy_backward
稍后配合源码进行说明;从稍后即将显示的源码可知,copy元素时一一进行元素的赋值操作,如果输出区间的起点位于输入区间内,copy算法便(可能)会在输入区间的(某些)元素尚未被复制之前,就覆盖其值,导致错误的结果。在这里我们一再使用可能这个字眼,是因为,如故宫copy算法根据其所接收迭代器的特性决定调用memmove()来执行任务,就不会造成上述错误,因为memmove(),会考虑重叠的情况再进行处理,保证不会出现值还没被拷贝就被覆盖的情况。以上就死copy()的故事,一个无所不用其极地强化执行效率的故事。原创 2024-11-29 22:05:01 · 697 阅读 · 0 评论 -
STL算法之基本算法<stl_algobase.h>
STL标准规格中没哟区分基本算法或复杂算法,然后SGI却把常用的一些算法定义于之中,其他算法定义于之中。以下一一列举这些基本算法。原创 2024-11-28 23:42:47 · 1172 阅读 · 0 评论 -
STL算法之数值算法<stl_numeric.h>
这一节介绍的算法,统称为数值(numeric)算法。STL规定,欲使用它们,客户端必须包含头文件.SGI将它们实现与文件中。原创 2024-11-27 21:49:02 · 1007 阅读 · 0 评论 -
STL之算法概览
算法,问题之解法也。以有限的步骤,解决逻辑或数学上的问题,这一专门科目我们称为算法(Algorithms)。大学信息相关教育里面,与编程最有关直接关系的科目,首推算法与数据结构(Data Structures,亦即STL中的容器)。STL算法即是将最被运用的算法规范出来,其涵盖区间有可能在每五年一次的c++标准委员会中不断增订。广义而言,我们所写的每个程序都是一个算法,其中的每个函数也都是一个算法,毕竟它们都用来解决或大或小的逻辑问题或数学问题。唯有用来解决特定问题(例如排序,查找,最短路径,三点共线。原创 2024-11-26 22:07:51 · 907 阅读 · 0 评论 -
STL关联式容器之hash_set、hash_map、hash_multiset、hash_multimap
虽然STL只规范复杂度与接口,并不规范实现方法,但STL set多半以RB-tree为底层机制。SGI则是在STL标准规格之外另又提供了一个所谓的hash_set,以hashtable为底层机制。由于hash_set所提供的操作接口,hashtable都提供了,所以几乎所有的hash_set操作行为,都只是转调用hashtable的操作行为而已。运用set,为的是能够快速搜寻元素。这一点,不论底层是RB-tree或是hashtable,都可以达成任务。原创 2024-11-25 21:48:51 · 1107 阅读 · 0 评论 -
STL关联式容器之hashtable
下图为开链法(separate chaining)完成hashtable的图形表述。为了了解SGI STL源码,我们遵循SGI的命名,称hash table表格内的元素为桶(bucket),此名称的大约意义是,表格内的每个单元,涵盖的不只是个节点(元素),可能是一桶节点。下面是hash table的节点定义注意,bucket所维护的linked list,并不采用STL的list或slist,而是自行维护上述的hashtable node。至于buckets聚合体,则以完成,以便有动态扩展能力。原创 2024-11-24 21:04:04 · 1075 阅读 · 0 评论 -
STL关联式容器之hashtable介绍
hash table可提供对任何有名项(named item)的存取操作和删除操作。由于操作对象是有名项,所以hash table也可被视为一种字典结构(dictionary)。这种结构的用意在与提供常数时间之基本操作,就像stack或queue那样。乍听之下这几乎是不可能的任务,因为制约条件如此至少,而元素个数增加,搜寻操作必行耗费更多时间。倒也不尽然。举个例子,如果所有的元素都是16-bits且不带正负号的整数,范围0~65535,那么简单的运用一个array就可以满足上述期望。原创 2024-11-23 22:32:01 · 803 阅读 · 0 评论 -
STL关联式容器之multiset及multimap
multiset的特性及用法和。原创 2024-11-23 16:45:33 · 286 阅读 · 0 评论 -
STL关联式容器之map
如果想要修正元素的键值,答案是不行的,因为map元素的键值关系到map元素的排列规则。如果想要修改元素的实值,答案是可以的,因为map元素的实值并不影响map元素的排列规则。pair的第一元素被视为键值,第二元素被视为实值。又由于map所开放的各种操作接口,RB-tree也都提供了,所以几乎所有的map操作行为,都只转调用RB-tree的操作行为而已。map拥有和list相同的某些性质:当客户端对它进行元素新增操作(insert)或删除操作(erase)时,操作之前的所有迭代器,在操作完成之后都依然有效。原创 2024-11-22 23:04:29 · 294 阅读 · 0 评论 -
STL关联式容器之set
又由于set所开放的各种操作接口,RB-tree也都提供了,所有几乎所有的set操作行为,都只是转调用RB-tree的操作行为而已。STL特别提供了一组set/multiset相关算法,包括交集set_intersection,联集set_union,差集set_difference、对称差集set_symmetric_difference,后续内容会进行描述。set的元素不像map那样可以同时拥有实值(value)和键值(key),set元素的键值就是实值,实值就是键值。(除了被删除的那个迭代器)原创 2024-11-22 20:41:54 · 298 阅读 · 0 评论 -
STL关联式容器之RB-tree(红黑树)_下
下面是rb-tree的定义。你可以看到其中定义有专属的空间配置器,每次用来配置一个节点的大小,也可以看到各种型别定义,用来维护整颗RB-tree的三笔数据(其中有个仿函数,functor,用来表现节点的大小比较方式),以及一些member function的定义或声明。原创 2024-11-21 22:23:19 · 781 阅读 · 0 评论 -
STL关联式容器之RB-tree(红黑树)_中
为了避免中情况4“父子节点皆为红色”的情况,持续向RB-tree的上层结构发展,形成处理时效上的瓶颈,我们可以施行一个由上而下的程序(top-down proceduce):假设新增节点为A,那么就沿着root往A的路径,只要看到有某个节点X的两个子节点皆为红色,就把X改为红色,并把两个子节点改为黑色,如下图所示:从根节点到新增节点A的路径,如下图所示,使用淡蓝色标识箭头方向:此时发现了节点50为X节点,解X变为红色,并将X的两个子节点变为黑色;原创 2024-11-20 22:17:50 · 927 阅读 · 0 评论 -
STL关联式容器之RB-tree(红黑树)_上
AVL-tree之外,另一个颇具历史并被广泛运用的平衡二叉搜索树是RB-tree(红黑树)。所谓RB-tree,不仅是一颗二叉搜索树,而且必须满足一下规则:1:每个节点不是红色就是黑色2:根节点为黑色3:若节点为红,其子节点必须为黑4:任意节点至NULL的任何路径,所含黑节点数必须相同。根据规则4,新增节点必须为红;根据规则3,新增节点之父节点必须为黑。当新节点根据二叉搜索树的规则到达其插入点,却未能符合上述条件时,就必须调整颜色并旋转树形。原创 2024-11-20 00:10:00 · 523 阅读 · 0 评论 -
STL关联式容器之平衡二叉搜索树
在中对二叉搜索树做了简要的描述;但是因为没有对二叉搜索树对数的深度及插入后树的结构进行调整,二叉搜索树可能失去平衡,造成搜寻效率低落的情况。如下所示:所谓树形平衡与否,并没有一个绝对的测量标准。“平衡”的大致意义是:没有任何一个节点过深(深度过大)。不同的平衡条件,造就不同的效率表现,以及不同的实现复杂度。原创 2024-11-18 23:13:22 · 797 阅读 · 0 评论 -
STL关联式容器介绍
在前文中介绍了STL的序列式容器;接下来对关联式容器(associative containers)进行学习及分享;根据“数据在容器中的排列”特性,容器可概分为序列式(Sequence)和关联式(associative)两种。标准的STL关联式容器分为set(集合)和map(映射表)两大类,以及两大类的衍生体multiset(多键集合)和multimap(多键映射表)。这些容器底层机制均以RB-tree(红黑树)完成。RB-tree也是独立容器,但并不开放给外界使用。原创 2024-11-17 21:12:19 · 1286 阅读 · 0 评论 -
STL序列式容器之slist
STL是个双向链表(double linked list)。SGI STL另提供了一个单向链表(single linked list),名为slist。slist和list的主要差别在于,前者的迭代器属于单向的ForwardIterator,后者的迭代器属于双向的BidrectionalIterator。为此,slist的功能自然也就受到许多限制。不过,单向链表所耗用的空间更小,某些操作更快,不失为另一种选择。原创 2024-11-17 14:07:15 · 787 阅读 · 0 评论 -
STL序列式容器之priority_queue
由于priority_queue完全以底部容器为根据,再加上heap处理机制,所以其实现非常简单。缺省情况下是以vector为底层容器。源代码很简短,此处完整列出。queue以底部容器完成所有工作。具有这种“修改某物接口,形成另一种风貌”之性质者,成为adapter(适配器),因此,STL priority_queue往往不被归类为container(容器),而被归类为container adapter。原创 2024-11-17 10:35:23 · 666 阅读 · 0 评论 -
STL序列式容器之heap(堆)
heap并不归属于STL容器组件,它是幕后英雄,扮演了priority queue的助手;priority queue允许用户以任意顺序将元素推入容器内,但是取出时,是按优先级最高的元素开始取。针对priority queue要求的特性,最直观的做法,有两种:1:插入后,保持底层queue的排序状态,此时插入的时间复杂度是O(n);取数据可在常数时间内将元素取出2:插入还是放在容器的末尾,插入的时间复杂度尾O(1);取数据时,需要遍历数组,而后取出最大的那个元素;时间复杂度为O(n);原创 2024-11-16 19:47:26 · 687 阅读 · 0 评论 -
STL序列式容器之queue
queue是一种先进先出(First In First Out,FIFO)的数据结构。它有两个出口,头和尾能分别进行pop及push;底层queue可以通过deque进行实现。更换queue的底层容器只需,在定义queue时指定Sequence时即可。原创 2024-11-15 21:24:03 · 248 阅读 · 0 评论 -
STL序列式容器之stack
stack允许新增元素、移除元素、取得最顶端元素。stack允许新增元素、移除元素、取得最顶端元素。单除了最顶端外,没有任何其它方法可以存取stack的其它元素。从以上定义可知,只需要实现了empty(),size(),back(),push_back(),pop_back()及operator ==及原创 2024-11-14 21:11:21 · 279 阅读 · 0 评论 -
STL序列式容器之deque
每次为deque分配一段Bufsize大小的空间,内部有一个map(存储缓冲区节点的连续空间)类似vector,动态伸缩的连续array以及需要随机索引访问元素的情况,(其随机访问迭代器效率基本还是可接受的,比list高,比vector低);vector也可以再头部进行数据的插入,但是效率会比较低(因为头部插入数据,vector中的所有数据都得进行移动);Iterator在执行--,是,优先在缓冲区中cur--,当cur==first是,node会--,同时cur会=last-1;原创 2024-11-13 22:30:02 · 316 阅读 · 0 评论 -
STL序列式容器之list
此外在书中,提到了sort函数,用的快排的代码,用到了swap及merge,没能理解,(可能是前面漏掉了部分函数的定义,没有理解算法的含义;此外,lsit还提供了splice及merge操作,splice用于拼接,merge是两个有序list的合并,看上去很适合归并排序当中的合并操作;对于操作符++,和--,分别对应于node=node->next,及node=node->pre;因为是环形结构,node本身即为list的end,node->next即为list的起始节点;list节点定义如下。原创 2024-11-12 21:46:08 · 810 阅读 · 0 评论 -
STL序列式容器之vector
两者唯一的区别是,array是静态空间,一旦初始化之后,空间不能改变;vector是stl序列式容器包括array(内建),vector,heap,priority-queue,list,slist,deque,stack, queue;在insert操作中,之前通常的理解是,vector会将插入位置的元素都往后移一位,而后在空出的位置插入元素;且内部有着类似数组的结构;在移动的过程中,如果可以使用赋值运算会优先使用赋值运算;对于基本数据类型,他们应该都是等效的;主要是自定义类,才会有一些效果上的差异;原创 2024-11-11 21:46:51 · 244 阅读 · 0 评论 -
迭代器与traits编程技法
const T*的value_type去除了const属性,主要是为了方便后续通过value_type定义变量进行使用;其中string即为interator的value_type;即是对于原始指针T*,及const T*,就没有了I::value_type的定义;其中int即为interator的value_type;迭代器,最基本的操作包括迭代器的++,--,+n,*及->操作;为了实现*,及->的操作,迭代器必须指定其型别;通过函数func可以获取迭代器中的值;原创 2024-11-10 21:06:20 · 367 阅读 · 0 评论 -
STL之空间配置器allocator
以STL的运用角度而言,空间配置器是最不需要介绍的东西,它总是隐藏在一切组件(更具体的说是指容器,container)的背后,默默的工作,默默付出。但若以STL的实现角度而言,第一个需要介绍的就是空间配置器,因为整个STL的操作对象(所有的数值)都存放在容器之内,而容器一定需要配置空间以放置资料。不先掌握空间配置器的原理,难免在阅读其它STL组件的实现时处处遇到挡路石。为什么不说allocator是内存配置器而说它是空间配置器呢?因为空间不一定是内存,空间也可以是磁盘或其它辅助存储介质。原创 2024-12-10 23:39:03 · 1169 阅读 · 0 评论