STL 源代码剖析 算法 stl_algo.h -- rotate
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
rotate
--------------------------------------------------------------
描写叙述:将[first, middle) 内的元素和[middle, last) 内的元素互换。
/*------------------------------------------------------------ *分派函数(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.当两段都结束时,循环结束
复杂度: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)
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