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
时间: 2024-10-07 14:21:46

STL 源代码剖析 算法 stl_algo.h -- rotate的相关文章

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

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search ------------------------------------------------------------------------- 描写叙述:在序列一[first1, last1) 所涵盖的区间中.查找序列二[first2, last2) 的首次出现点. 思路: 1.遍历序列二 2.假设两序列的当前元素一样,都前进 1 3.否则序列二的迭代器又一次指向開始元素

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

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie equal_range(应用于有序区间) -------------------------------------------------------------------------------------------------------------------------------------- 描写叙述:利用二分查找找到一个区间,区间里的全部值都等于给定值,返回的是一个pa

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

本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie inplace_merge(应用于有序区间) -------------------------------------------------------------------- 描写叙述:假设两个连接在一起的序列[first, middle)和 [middle, last]都已排序, 那么 inplace_merge 可将它们结合成单一一个序列,并仍有序. 源代码: template

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

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie lower_bound(应用于有序区间) -------------------------------------------------------------------------------------------------------------------------- 描写叙述:二分查找,返回一个迭代器指向每个"不小于 value "的元素, 或 value 应

STL 源码剖析 算法 stl_algo.h -- rotate

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie rotate -------------------------------------------------------------- 描述:将[first, middle) 内的元素和[middle, last) 内的元素互换. 图6-6g /*------------------------------------------------------------ *分派函数(dis

STL 源代码分析 算法 stl_algo.h -- includes

本文senlie原,转载请保留此地址:http://blog.csdn.net/zhengsenlie includes(应用于有序区间) ------------------------------------------------------------- 描写叙述:S1和S2都必须是有序集合.推断序列二 S2 是否"涵盖于"序列一 S1,即"S2的每个元素是否都出现于 S1中" 思路: 1.遍历两个区间.直到当中一个走完 2.假设序列二的元素小于序列一的元素

STL 源代码分析 算法 stl_algo.h -- binary_search

本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie binary_search ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 描

STL 源代码分析 算法 stl_algo.h -- pre_permutation

本文senlie原版的,转载请保留此地址:http://blog.csdn.net/zhengsenlie pre_permutation ---------------------------------------------------------------- 描写叙述: 取得 [first, last) 所标示之序列的前一个排列组合. 假设没有,返回 false,有,返回true 思路: 从后往前 1.找两个相邻元素,令左端的元素为*i,右端的元素为*ii,且满足 *i > *ii 2

STL 源码剖析 算法 stl_algo.h -- search_n

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search_n ---------------------------------------------------------------------------------------- 描述:在序列[first, last) 所涵盖的区间中,查找"连续 count 个符合条件之元素"所形成的子序列, 并返回迭代器 last 思路: 1.首先找出 value 第一次出现点