迭代器设计

本文采用知识共享署名 4.0 国际许可协议进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,可适当缩放并在引用处附上图片所在的文章链接。

目录

迭代器简介

迭代器与容器

为什么引入Iterator

使用迭代器实现冒泡排序

迭代器接口

算法接口


迭代器简介

迭代器与容器

在初始化数组中的元素时,通常使用下面这样的for循环语句遍历数组:

int i, a[10];

for(i = 0; i < 10; i++)

a[i] = i;

这段代码中的循环变量i,该变量的初始值为0,然后递增为1、2、3、...,程序在每次i递增后都将值赋给a[i]。数组中保存了许多元素,通过指定数组下标,即可从中选择任意一个元素。for语句中的i++的作用是让i的值在每次循环后自增1,这样就可以访问数组中的下一个元素,从而实现了从头到尾逐一遍历数组元素的功能。

由此可见,常用的循环结构就是一种迭代操作,在每一次迭代操作中,对迭代器的修改即等价于修改循环控制的标志或计数器。而容器是一种保存值的集合的数据结构,C有两种内建的容器:数组和结构体。虽然C没有提供更多的容器,但用户可以按需编写自己的容器,比如,链表、哈希表等。将i的作用抽象化、通用化后形成的模式,在设计模式中i称为迭代器(Iterator)模式,Iterate的字面意思是重复、反复声明,其实就是重复做某件事,Iterator模式用于遍历数组中的元素。迭代器的基本思想是迭代器变量存储了容器的某个元素的位置,因此能够遍历该位置的元素。通过迭代器提供的方法,可以继续遍历容器的下一个元素。

显而易见,迭代器是一种抽象的设计概念,因为在程序设计语言中并没有直接对应于这个概念的实物。《设计模式》一书提供了 23种设计模式的完整描述,其中iterator模式的定义为:在遍历一个容器对象时,提供一种方法顺序访问一个容器对象中的各个元素,而又不暴露该对象的内部表示方式。其中心思想是将数据容器和算法分开且彼此独立,最后再用黏合剂将它们撮合在一起。

为什么引入Iterator

这种复杂的设计模式呢?如果是数组,直接使用for循环语句进行遍历处理不就可以了吗?为什么要在集合之外引入Iterator这个角色呢? 一个重要的理由是,引入Iterator后可以将遍历与实现分离。

实际上无论是单向链表还是双向链表,其查找算法与遍历算法的实现没有多少差别,基本上都是重复劳动。如果代码中有bug,则需要修改所有相关的代码。为什么会出现这样的情况呢?主要是接口设计不合理所造成的,其最大的问题就是将容器和算法放在了一起,且算法的实现又依赖于容器的实现,因而必须为每一个容器开发一套与之匹配的算法。

假设要在2种容器(双向链表、动态数组)中分别实现6种算法(交换、排序、求最大值、求最小值、遍历、查找),显然需要2X6=12个接口函数才能实现目标。随着算法数量的不断增多,势必导致函数的数量成倍增加,重复劳动的工作量也越大。如果将容器和算法单独设计,则只需要实现6个算法函数就行了。即算法不依赖容器的特定实现,算法不会直接在容器中进行操作。比如,排序算法无需关心元素是存放在数组或线性表中。

使用迭代器实现冒泡排序

迭代器接口

typedef void *iterator_t;
typedef void (*iterator_next_t)(iterator_t *p_iter);
typedef void (*iterator_prev_t)(iterator_t *p_iter);
typedef int (*visit_t)(void *p_arg, iterator_t it);

typedef struct _iterator_if
{
    iterator_next_t pfn_next;
    iterator_prev_t pfn_prev;
} iterator_if_t;


void iterator_if_init(iterator_if_t *p_if, iterator_next_t pfn_next, iterator_prev_t pfn_prev);
void iterator_next(iterator_if_t *p_if, iterator_t *p_iter);
void iterator_prev(iterator_if_t *p_if, iterator_t *p_iter);
void iterator_foreach(iterator_if_t *p_if, iterator_t begin, iterator_t end, visit_t visit, void *p_arg);

算法接口

typedef int (*compare_t)(iterator_t it1, iterator_t it2);
typedef void (*swap_t)(iterator_t it1, iterator_t it2);

void iter_sort(iterator_if_t *p_if, iterator_t begin, iterator_t end, compare_t compare, swap_t swap);

代码地址:https://github.com/zhangyuhu/algorithm_data_structure/tree/master/c/ZLG/%E8%BF%AD%E4%BB%A3%E5%99%A8

运行环境:C Free 5.0

运行效果:

说明:内容摘抄自周立功的书籍《 程序设计与数据结构》,地址为:http://www.zlg.cn//foxmail/weixinpdf/20170503.pdf

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

002237

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值