STL源码剖析—算法
在STL中的算法中一些算法是可以根据算法名字来判断算法作用的。所有算法的参数都是迭代器,不过不同的算法调用的迭代器类型也是不同的。多有的STL算法都作用在由迭代器{first,lase)所表示出来的区间上。拷贝(copy)交换(swap)替换(replace)填写(fill)删除(remove)排列组合(permutation)分割(partition)随机重排(random shuffling)排序(sort)计算(accumulate)计数(count)匹配(search)查找(find)比较(equal
mismatch)寻找极值。而且在有的函数中需要一些仿函数。
所有泛型算法的前两个参数都是一对迭代器,采用前闭后开形式。不过有的函数中不仅仅有两个参数,可能还有一个迭代器,还有一个接收仿函数的参数。
Next_permutation,求下面的一个排列,对于有序区间来说,实现的方法如下:
从最尾端开始往前寻找两个相邻元素,领第一元素为*I,第二元素为*II,且满足*i< *ii.找到这样一组相邻元素后,再从尾端开始往前检验,找出第一个大于*i的元素,令为*j,将I,j元素对调,再将ii之后的元素颠倒排列(当然包括ii)。此即所求之“下一个”排列数组。
这里所说的第一个元素和第二个元素分别代表*i和*ii.*i始终在*ii左边。
Partial_sort排序,本算法接受一个middle迭代器(位于序列[first,last)之内),然后重新安排[first,last),使序列中的middle-first个最新元素以递增顺序排序,置于[first,middle)内,其余last-middle个元素安置于[middle,last)中,不保证有任何特定顺序。
Sort算法接受两个randomaccessiterators(随机存取迭代器),然后将区间内的所有元素以渐增方式由小到大重新排列。第二个版本则允许用户指定一个仿函数,作为排序标准。STL的所有关系型容器都拥有自动排序动能(底层结构采用RB-tree)。所以不需要这个sort算法。至于序列式容器中的stack、queue和priority-queue都有特定的出入口,不允许用户对元素排序。剩下vector、deque和list,前两者的迭代器属于Randromaccessiterator,适合使用sort算法,list的迭代器则属于forwarditerators,都不适合使用sort算法。如果要对List或slist排序,应该使用它们自己提供的sort()函数。
Nth_element,这个算法会重新排列[first,last)。使迭代器nth所指的元素,与“整个[first,last)完整排序后,同一个位置的元素”同值。此处并宝恒[nth,last)内没有任何一个元素小于[first,last)内的元素,但对于[first,nth)和[nth,last)两个子区间的元素次序则无任何保证—这一个点也是它与partial_sort很大的不同处。
什么意思呢?比如一个向量存储整数,首先这个函数可以接受三个迭代器,使得以第二个迭代器所指的元素作为关键词,将整个区间分段同时使得第二个迭代器指向的原始元素在整个区间中的位置正好是第二个迭代器的位置。
举例说明:
{20,30,30,17,33,40,17,23,22,12,20},以下操作:
Nth_element(iv.begin(), Iv.begin()+5,iv.end());
便是将小于 *(iv.begin()+5)(本例为40)的元素置于该元素之左,其余置于该元素之右,并且不保证维持原有的相对位置。获得的结果为{20,12,22,17,17,22,23,30,30,33,40}。执行完毕后第五个元素位置上的元素值为22,与整个序列完整排序后{12,17,17,20,22,22,23,30,30,33,40}的第五个位置上的元素值相同。
如果以上述结果{20,12,22,17,17,22,23,30,30,33,40}为根据,在执行以下操作:
Nth_element(iv.begin(), Iv.begin()+5,iv.end());
那便是将大于*(iv.beng()+5)(本例为22)的元素置于该元素之左,其余置于该元素之右,并且不保证维持原有的相对位置,获得的结果为{40,33,30,30,23,22,17,17,22,12,20}。