描写叙述:将[first, middle) 内的元素和[middle, last) 内的元素互换。

STL 源代码剖析 算法 stl_algo.h -- rotate_javascript

/*------------------------------------------------------------
*分派函数(dispatch function)
*/
template <class ForwardIterator>
inline void rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last){
if(first == middle || middle == last) return ;
__rotate(first, middle, last, distance_type(first), iterator_category(first));
}


以下依据不同的迭代器类型完毕三个旋转操作


rotate 的 forward iterator 版

思路:

1.以短段为根据。相应元素逐一对调

2.调整,对新的前、后段再作交换

3.当两段都结束时,循环结束

STL 源代码剖析 算法 stl_algo.h -- rotate_复杂度_02

复杂度:O(n)

template<class ForwardIterator, class Distance>
void __rotate(ForwardIterator first, ForwardIterator middle,
ForwardIterator last, Distance*, forward_iterator_tag){
for(ForwardIterator i = middle ; ; ){
iter_swap(first, i); //前段,后段的元素一一交换
++first; ++i; // 双双前进 1
// 下面推断是前段[first, middle)先结束还是后段 [middle, last) 后结束
if(first == middle){ //前段结束了
if(i == last) return; //假设后段同一时候也结束,整个就结束了
middle = i;
}
else if(i == last){ //后段先结束
i = middle; // 调整。准备对新的的前、后段再作交换
}
}
}


rotate 的 bidirectional iterator 版

思路:

1.对前段逆转

2.对后段逆转

3.对总体逆转

复杂度:O(n)

STL 源代码剖析 算法 stl_algo.h -- rotate_ide_03

template<class BidirectionalIterator, class Distance>
void __rotate(BidirectionalIterator first, BidirectionalIterator middle,
BidirectionalIterator last, Distance *,
bidirectional_iterator_tag){
reverse(first, middle);
reverse(middle,last);
reverse(first, last);
}


rotate 的 random access iterator 版 --> ?? 看不太懂。。。


template<class RandomAccessIterator, class Distance>
void __rotate(RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last, Distance *,
random_access_iterator_tag){
//取全长和前段长度的最大公因子
Distance n = __gcd(last - first, middle - first);
while(n--){
__rotate_cycle(first, last, first + n, middle - first, value_type(first));
}
}

template <class EuclideanRingElement>
EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n)
{
while (n != 0) {
EuclideanRingElement t = m % n;
m = n;
n = t;
}
return m;
}

template <class RandomAccessIterator, class Distance, class T>
void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last,
RandomAccessIterator initial, Distance shift, T*) {
T value = *initial;
RandomAccessIterator ptr1 = initial;
RandomAccessIterator ptr2 = ptr1 + shift;
while (ptr2 != initial) {
*ptr1 = *ptr2;
ptr1 = ptr2;
if (last - ptr2 > shift)
ptr2 += shift;
else
ptr2 = first + (shift - (last - ptr2));
}
*ptr1 = value;
}


演示样例:

char alpha[] = "abcdefghijklmnopqrstuvwxyz";
rotate(alpha, alpha + 13, alpha + 26);
printf("%s\n", alpha);
// The output is nopqrstuvwxyzabcdefghijklm