首页 > 编程语言 >C++:使自定义类支持迭代器

C++:使自定义类支持迭代器

时间:2024-09-10 18:35:14浏览次数:9  
标签:cur 自定义 int Iterator C++ 节点 链表 迭代

概述


在 C++ 中,链表迭代器是一种用来遍历链表(如 std::list)元素的工具。链表是一种数据结构,其中每个元素(节点)包含一个数据值和一个指向下一个节点的指针。链表迭代器允许以类似于数组的方式访问链表中的元素,但不需要直接操作指针。

链表迭代器的作用

  • 访问元素:链表迭代器使你能够顺序访问链表中的每个元素,就像在数组中遍历元素一样。

  • 遍历链表:通过迭代器,你可以在链表中前进或后退,从而进行遍历操作。这使得在链表中执行各种操作(如查找、修改、删除等)变得简单而直观。

  • 抽象化操作:迭代器提供了一种统一的方式来访问不同类型的数据结构。无论是链表、数组还是其他容器,迭代器的使用方式大致相同,这让代码更加通用和易于维护。

使用示例


#include <iostream>
#include <list>

int main() {
    std::list<int> myList = {1, 2, 3, 4, 5};
    
    // 使用迭代器遍历链表
    for (std::list<int>::iterator it = myList.begin(); it != myList.end(); ++it) {
        std::cout << *it << " ";  // 输出链表元素
    }
    
    return 0;
}

为什么要为自己的类设置迭代器?


参考下述链表类

class List {
public:
    List(): head(new Node()) { }
    ~List();

    bool push(int x, int y);    // 在头部插入一个新坐标
    bool pop(int x, int y);     // 查找指定坐标,并删除

private:
    Node* head;
};

在该链表中,定义了pushpop两个方法,现假定,我们需要能够从第一个节点开始,逐步在外部调用链表的每一个节点,有一种简单的实现方法:

  • 定义search(int i)函数,从头开始,向后查询i个节点
  • 在外部采用for循环递增节点索引i

这里给出一个伪代码:

for (int i = 0; i < 10; ++i) {
    Node cur = myList.search(i);
    std::cout << cur << std::endl;
}

上述方法能够实现在外部对链表节点的遍历,但是,当索引较大时,鉴于每一次都需要从头访问至索引处,算力开销极大,因此我们必须采用更高效的方法。

如何为类设置迭代器方法?


观察标准库中迭代器的使用方法:

for (std::list<int>::iterator it = myList.begin(); it != myList.end(); ++it) {
        std::cout << *it << " ";  // 输出链表元素
}

我们了解到需要实现如下内容:

  • 定义迭代器类,包含一个Node*类型的指针cur,指向当前元素。
  • 在链表类中,定义beginend函数,分别指向第一个元素和尾节点。
  • 定义!=运算符,以支持比较两个指针是否相同。
  • 定义++运算符,使得可以更便携的遍历节点。
  • 定义*运算符,使得可以采用指针方法访问到节点的值。

我们可以依次完成实现

class List {
public:
    List() : head(new Node()) { }
    ~List();

    bool push(int x, int y);
    bool pop(int x, int y);

    // 定义迭代器类
    class Iterator {
    public:
        // 构造函数
        Iterator(Node* node) : cur(node) {}
        // 指针运算符
        Cell& operator*() { return cur->cell; }
        // 前置自增运算符
        Iterator& operator++() {
            if (cur) cur = cur->next;
            return *this;
        }
        // 不等于运算符
        bool operator!=(const Iterator& other) const { return cur != other.cur; }

    private:
        // cur字段
        Node* cur;
    }

    // 分别定义begin()、end()方法
    Iterator begin() const { return Iterator(head->next); }
    Iterator end() const { return Iterator(nullptr); }

private:
    Node* head;
};

完成上述实现后,我们就可以使用迭代器方法快捷的访问类成员了。

#include <iostream>
#include "list.h"

int main() {
    List ROI;
    // 插入节点
    ROI.push(0, 0);
    ROI.push(0, 1);  
    ROI.push(0, 2);
    ROI.push(0, 3);

    for (List::Iterator it = ROI.begin(); it != ROI.end(); ++it) {
        std::cout << *it << "\n";
    }

    return 0;
}

标签:cur,自定义,int,Iterator,C++,节点,链表,迭代
From: https://www.cnblogs.com/SXWisON/p/18405181

相关文章

  • C++ 多线程详解:从基础到应用
    目录一、什么是多线程?二、C++中的多线程支持三、总结在现代应用中,多线程成为了提升程序性能的重要工具。特别是当我们希望充分利用多核CPU的计算能力时,C++提供了强大的多线程支持,可以并发地执行多个任务。今天,我们将通过易懂的讲解与实际的代码示例,帮助你掌握C+......
  • C++环境搭建(Visual Studio 2022软件安装)
    安装环境:Windows11家庭中文版VisualStudio2022下载地址:        https://pan.baidu.com/s/15U8AEIwThxp-fAZFJqnCgQ    提取码:0000 安装步骤:        1.下载后选择安装包进行解压。    2.以管理员身份运行安装程序。(企业版功能最全,这......
  • WTForms中如何自定义字段类型
    在WTForms中,自定义字段类型通常涉及创建一个新的类,该类继承自wtforms.Field或其任何子类,并根据需要重写方法以实现特定的行为。以下是一个简单的例子,展示了如何创建一个自定义的字段类型:pythonfromwtformsimportField,validatorsclassMyCustomField(Field):def_......
  • C++入门知识
    目录C++是什么C++关键字(c++98)命名空间(namespace)命名空间的定义 命名空间使用声明和定义 C++的输入输出缺省函数缺省函数是什么?全缺省半缺省注意一:半缺省只能从右向左给,并且不能中断 缺省函数不能同时在声明和定义中出现缺省的参数只能是全局的或者常数函数......
  • C++中STL容器的使用
    容器一些基本操作语法vector初始化操作vector<int>a;//声明向量vector<int>a(10);//声明一个初始大小为10的向量vector<int>a(10,1);//初始大小为10,且值都为1的向量vector<int>b(a);//声明并用向量a初始化向量bvector<int>b(a.begin(),a.begin()+3);//将......
  • 最简单C++线程和互斥锁使用示例
    std::thread是C++11标准库中引入的一个类,用于表示一个独立的执行线程。而std::mutex是C++11中提供的一种互斥锁,用于在多个线程间同步对共享数据的访问,以避免数据竞争和条件竞争。下面将分别介绍std::thread和std::mutex的基本使用,并通过一个示例展示它们的结合使用......
  • 【Py/Java/C++三种语言OD独家2024E卷真题】20天拿下华为OD笔试之【回溯】2024E-字符串
    可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入描述输出描述示例一输入输出说明示例二输入输出说明解题思路代码pythonjavacpp时空复杂度华为OD算法/大厂面......
  • 【Harmony】文本高亮显示、关键字凸显字体大小、颜色、背景色等风格自定义、嵌入html
    预览效果如图(网上找到demo,如有疑问请留评论蛤!):这个是超链接例子的数据结构如下:newCustomMessage($r('app.media.styled_text_user_image1'),'央视新闻','2小时前',[newCustomSpan(CustomSpanType.Normal,'【准备回家!'),newCustomSpan(CustomSpanType.Hasht......
  • 【C++】priority_queue讲解
    一、priority_queue的本质priority_queue的本质就是堆,添加的元素按照堆的规则存储,默认情况下是大堆。二、priority_queue的参数priority_queue有三个参数。intmain(){priority_queue<int,vector<int>,less<int>>s;//第一个参数为要存放的数据类型//第......
  • C++学习笔记(14)
    二、栈解旋异常被抛出后,从进入try语句块开始,到异常被抛出之前,这期间在栈上构造的所有对象,都会被自动析构。析构的顺序与构造的顺序相反。这一过程称为栈的解旋。也就是在执行throw前,在try执行期间构造的所有对象被自动析构后,才会进入catch匹配。在堆上构造的对象肿......