list类模拟实现

list类的模拟实现

目录

  1. 结点
  2. 框架
  3. 迭代器
    1. 初次尝试
    2. const迭代器

完整代码

1.结点

一个结点需要包含:储存的数据,上一个结点的地址,下一个结点的地址。

c++ 复制代码
template<class T>
struct __list_node
{
    __list_node<T>* _prev;
    __list_node<T>* _next;
    T _data;

    __list_node(const T& x = T())	//T()是匿名类型,如果没有传参,编译器会调用相应类型的构造函数
        :_data(x)
        ,_prev(nullptr)
        ,_next(nullptr)
    {}
};
  • 由于我们后面会在类外访问,所以为了避免麻烦就写成struct,这样成员属性都是public的。
  • 使用模板,方便适配各种数据类型

2.框架

list类包含哨兵结点的指针

c++ 复制代码
template<class T>
class list
{
public:
    typedef __list_node<T> Node;
    
    list()
    {
        _head = new Node;
        _head->_next = _head;
        _head->_prev = _head;
    }
    
private:
    Node* _head;
};    
  • 因为是双向循环链,所以哨兵结点的指针都指向自己

3.迭代器

list的迭代器的实现,是模拟list实现的重中之重

3.1初次尝试

  • list迭代器的本质还是指针
  • 我们将指针的封装,内部进行运算符重载
c++ 复制代码
template<class T>
struct __list_iterator
{
    typedef __list_node<T> Node;
    typedef __list_iterator<T> Self;
    Node* _node;

    __list_iterator(Node* node)
        :_node(node)
    {}

    T& operator*()
    {
        return _node->_data;
    }

    T* operator->()
    {
        return &_node->_data;
    }

    Self& operator++()
    {
        _node = _node->_next;
        return *this;
    }

    Self operator++(int)
    {
        Self tmp(*this);
        //_node = _node->_next;
        ++(*this);
        return tmp;
    }

    Self& operator--()
    {
        _node = _node->_prev;
        return *this;
    }

    Self operator--(int)
    {
        Self tmp(*this);
        //_node = _node->_next;
        --(*this);
        return tmp;
    }

    bool operator!=(const Self& it)const
    {
        return _node != it._node;
    }

    bool operator==(const Self& it)const
    {
        return _node == it._node;
    }
};
  • 就是将++/--的操作通过运算符重载,变成在结点间移动的操作。

3.2const迭代器

  • list的迭代器不像vector/string类的迭代器,它不可以直接在迭代器的前面加const修饰
  • 指针被const修饰后,不能通过指针来修改数据,意味着operator*operator->的作用失效,但其他函数还能继续使用
  • 如果再专门写一份const的迭代器,那么代码就太过冗余了
c++ 复制代码
template<class T, class Ref, class Ptr>
struct __list_iterator
{
    typedef __list_node<T> Node;
    typedef __list_iterator<T, Ref, Ptr> Self;
    Node* _node;

    __list_iterator(Node* node)
        :_node(node)
    {}

    Ref operator*()
    {
        return _node->_data;
    }

    Ptr operator->()
    {
        return &_node->_data;
    }

    Self& operator++()
    {
        _node = _node->_next;
        return *this;
    }

    Self operator++(int)
    {
        Self tmp(*this);
        //_node = _node->_next;
        ++(*this);
        return tmp;
    }

    Self& operator--()
    {
        _node = _node->_prev;
        return *this;
    }

    Self operator--(int)
    {
        Self tmp(*this);
        //_node = _node->_next;
        --(*this);
        return tmp;
    }

    bool operator!=(const Self& it)const
    {
        return _node != it._node;
    }

    bool operator==(const Self& it)const
    {
        return _node == it._node;
    }
};
  • 这样,如果是const迭代器,就传const修饰的指针和引用。
相关推荐
闪电麦坤958 分钟前
数据结构:在二叉搜索树中插入元素(Insert in a BST)
数据结构·二叉树··二叉搜索树
闪电麦坤9512 分钟前
数据结构:用链式队列实现层序遍历 (Level-order Traversal)
数据结构··遍历
喜欢吃燃面25 分钟前
C++算法竞赛:位运算
开发语言·c++·学习·算法
草莓熊Lotso28 分钟前
《详解 C++ Date 类的设计与实现:从运算符重载到功能测试》
开发语言·c++·经验分享·笔记·其他
困鲲鲲28 分钟前
CPP多线程2:多线程竞争与死锁问题
c++·多线程·死锁
快乐的划水a9 小时前
组合模式及优化
c++·设计模式·组合模式
星星火柴93610 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
艾莉丝努力练剑11 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
闪电麦坤9512 小时前
数据结构:迭代方法(Iteration)实现树的遍历
数据结构·二叉树·
Cx330❀13 小时前
【数据结构初阶】--排序(五):计数排序,排序算法复杂度对比和稳定性分析
c语言·数据结构·经验分享·笔记·算法·排序算法