写在前面
在C++中rotate函数有多中重载类型,这里只讨论一种情况,当STL中对应容器的迭代器类型为ForwardIteartor以及更低的情况,我们不开辟新的空间,直接在容器上完成旋转,不借助任何其余空间。
函数原型
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)); //根据迭代器类型的不同,选择对应最快的计算方式
}
根据不同的迭代器类型,进行不同的操作,对于ForwardIteartor以及更低的类型而言,不能进行双向操作,所以不能使用reverse函数,并且再次申请空白内存区域会造成额外的时间空间上的浪费,所以我们直接在原来容器的基础上直接进行旋转操作
实现方法
#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;
template<class T>
struct display{
operator()(T a){
cout<<a<<" ";
}
};
template<class T>
void _rotate(T first,T middle,T last)
{
for(T i = middle;;){
swap(*first,*i);
++first;
++i;
if(first == middle){ //当前半段互换完成
if(i == last) return ; //同时后半段互换完成,那么表示,整体已经互换完成,可以直接退出
middle = i; //否则表示后半段还没有互换完成,讲middle指向i位置,继续进行互换
}
else if(i == last) //表示后半段互换完成,则将i重新指回middle,继续进行
i = middle;
}
}
int main()
{
int a[] = {0,1,2,3,4,5,6,7,8,9};
_rotate(a,a+7,a+10);
for_each(a,a+10,display<int>());
cout<<endl;
return 0;
}
函数原型
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;
if (first == middle) {
if (i == last) return;
middle = i;
}
else if (i == last)
i = middle;
}
}
后记
感觉这是一个十分精巧的实现方法,在这里记录一下
参考书籍
《STL源码剖析》侯捷著