Ruminations on C++__迭代器

(1)输入迭代器

 什么是输入迭代器呢,我们从一个例子出发进行说明.find函数看上去很简单,但是已经足以说明输入迭代器包含的基本要素了。如果一个对象p希望完全模拟指向序列的指针,那么必须有如下操作:解引用(*) 自加(++) 不等于判断(!=)以便实现取出序列某个元素值 并移动到下一个元素 也能够判断是否到达了最后一个元素的操作。为了完善起见 ++操作包括前++ 和后++以及==操作 。同时我们也能够复制p。满足这些需求之后 我们就能够按照预先规定的顺序读(不能写)序列中的元素。出于这样的原因 ,我们将这样的类型叫做输入迭代器。这里要强调一点就是输入迭代器既不是某个特殊类型也不是对象,相反,其只是一个概念,指的是满足上述要求的完整类型集合中的任意成员。换句话说 只要某个类型满足这些条件,就可以叫做输入迭代器。

/*
find函数的例子 
*/
template<class P,class T>
P find(P start,P end,const T& x)
{
    while(start !=end&& *start != x)
    {

    ++start;
    }
    return start;
}

  (2)输出迭代器

如果我们可以读取一个序列,那么也有相应的类型进行写操作,也就是所谓的输出迭代器。所谓的输出迭代器,和输入迭代器唯一的区别就是*p对于输出迭代器,希望是能够写*p,而不一定能够读,因为*p在被操作之前,可能是个无法被复制的有效值。

/*
该代码描述了输出迭代器的基本行为
*/
template<class In,class Out>
void copy(In start, In end ,Out result)
{
    while(start != end)
    {
        *result++ = *start++;
    }

}

 (3)前向迭代器

前向迭代器就是具有输入迭代器和输出迭代器功能的迭代器

/*
所谓的前向迭代器就是输入迭代器和输出迭代器的集合, f()是一个仿函数,长起来像函数的对象,其重载了()运算符
*/
template <class Iter , class Function>
void  apply( Iter start ,Iter end,Function f)
{

        while(start != end)
        {

            *start = f(*start);
        }
}

 (4)双向迭代器 

所谓的双向迭代器,就是既能够向前遍历也能够向后遍历的迭代器,与前向迭代器的区别在于其增加了--的操作。

template<class P, class T>
void reverse(P start ,P end)
{
    while(start !=end)
    {
        --end;
        if(start != end)
        {
            T t = *start;
            *start = *end;
            *end =t;
            ++start;
        }
    }
}

 (5)随机迭代器

有些算法必须高效的访问数据结构中的任意元素 如二分查找 为了支持二分查找 必须增加 + 、-、+=、-=操作增加到双向迭代器中,这样就构成了所谓的随机迭代器。

/*
二分查找
*/
template<typename T, typename X>
T binaryserch(T start, T end ,X x)
{
        T low =start;
        T high = end;
       
        while(low !=high)
        {
         T mid =(low + high) /2;
            if(*mid == x)
                return mid;
            if(x <*mid)
            high = mid;
            else
            low = mid +1;
        }
        return end;
}

 

所谓的泛型算法,就是这样的算法,对于所操作的数据结构的细节信息,只加入最低限度的了解。当然,理想的情况根本是不需要这样的信息,但是现实却不是这样的。作为一种折中,STL根据数据结构能够支持的有效操作,将这些数据结构进行分类,然后根据每一个算法,他会指出所需要的数据结构。

  被分类的不是算法,也不是数据结构,而是用来访问数据结构的类型,这些类型的对象叫做迭代器,迭代器一共有5种,输入 输出迭代器 前向迭代器 双向迭代器和随机存取迭代器。概念继承将这些种类联系在一起。

 这一整套结构使得我们很容易判断何种算法应该作用于何种数据结构上面。该结构也提供了一种框架,其他人可以根据这个框架来补充程序库之外的新算法。

/*
对于数组这种数据结构来说,遍历可以采用的事双向迭代器,因为对于其自身来说,支持自加和自减操作。
*/
void  reverse(int * start ,int * beyond)
{
 while(start != beyond)
    {
   int  t = *start;
    --beyond;
    *start = *beyond;
    *beyond = t;
    ++start;
    }
}
/*

对于单向链表来说,本身不支持自减操作 或者说自减操作的代价太大 因而这样的遍历可以采用双向迭代器
*/

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值