【手撕】list

系列文章目录


文章目录


前言

模拟实现list类


STL3.0(SGI版本)

list_node(节点)

cpp 复制代码
//节点类
template<class T>
struct list_node
{
    //成员变量
    list_node<T>* _next;
    list_node<T>* _prev;
    T _data;

    //构造函数
    list_node(cosnt T& x = T())
    :_next(nullptr)
    , _prev(nullptr)
    ,_data(x)
    {

    }
};

_list_iterator<T, Ref, Ptr>(迭代器)

成员变量

cpp 复制代码
  template<class T, class Ref, class Ptr>
  struct _list_iterator
  {//用类来封装node*
      typedef list_node<T> node;
      typedef _list__iterator<T, Ref, Ptr> self;
      node* _node;


  };

构造函数

cpp 复制代码
//构造函数
_list_iterator(node* n)
    :_node(n)
{

}

运算符重载

cpp 复制代码
//Iterator
Ref operator*()
{
    return _node->_data;
}

Ptr operator->()
{//it->_a1 => it->->_a1;
    return &_node->_data;
}

self& operator++()
{
    _node = _node->_next;

    return *this;
}

self operator++(int)
{
    self tmp(*this);
    _node = _node->_next;

    return tmp;
}

self& operator--()
{
    _node = _node->_prev;

    return *this;
}

self operator--(int)
{
    self tmp(*this);
    _node = _node->_prev;

    return tmp;
}

bool operator !=(const self& s)
{
    return _node != s._node;
}

bool operator ==(const self& s)
{
    return _node == s._node;
}

ReverseIterator<Iterator, Ref, Ptr>(反向迭代器)

cpp 复制代码
namespace yyf
{
	template<class Iterator, class Ref, class Ptr>
	struct ReverseIterator
	{
		//封装了_list_iterator<T,Ref,Ptr>
		typedef ReverseIterator<Iterator, Ref, Ptr> Self;
		Iterator _cur;

        //构造
        ReverseIterator(Iterator it)
            :_cur(it)
        {}

        Ref operator*()
        {
            Iterator tmp = _cur;
            --tmp;
            return *tmp;
        }

        Ptr operator->()
        {
            return &(operator*());
        }

        Self& operator++()
        {
            --_cur;
            return *this;
        }

        Self operator++(int)
        {
            Self tmp = _cur;
            --_cur;
            return tmp;
        }

        Self& operator--()
        {
            ++_cur;
            return *this;
        }

        Self operator--(int)
        {
            Self tmp = _cur;
            ++_cur;
            return tmp;
        }

        bool operator !=(const Self& s)
        {
            return _cur != s._cur;
        }

        bool operator ==(const Self& s)
        {
            return _cur == s._cur;
        }
	};
}

List(链表)

成员变量

cpp 复制代码
template<class T>
class list
{
    typedef list_node<T> node;

public:
    typedef _list_iterator<T, T&, T*> iterator;
    typedef _list_iterator<T, const T&, const T*>const_iterator;
  
    //typedef _list_const_iterator<T> const_iterator;
    typedef ReverseIterator<iterator, T&, T*> reverse_iterator;
    typedef ReverseIterator<iterator, const T&, const T*> const_reverse_iterator;    

private:
    node* _head;
    //节点指针
};

构造函数

cpp 复制代码
void empty_init()
{
    //创建头节点
    _head = new node;
    _head->_next = _head;
    _head->_prev = _head;
}

list()
{
    empty_init();
}

析构函数

cpp 复制代码
//析构函数
~list()
{	
    clear();
    //释放头节点
    delete _head;
    _head = nullptr;
}

区间构造函数

cpp 复制代码
template <class Iterator>
list(Iterator first, Iterator last)
{
    empty_init();
    while (first != last)
    {
        push_back(*first);
        ++first;
    }
}

拷贝构造

cpp 复制代码
void swap(list<T>& lt)
{
    std::swap(_head, lt._head);
}

list(const list<T>& lt)
{
    empty_init();
    list<T> tmp(lt.begin(), lt.end());
    swap(tmp);
}

赋值重载

cpp 复制代码
list<T>& operator=(list<T> tmp)
{
    swap(tmp);
    return *this;
}

Modifiers(修改器)

cpp 复制代码
void push_back(cosnt T& x)
{
    insert(end(), x);
}

void push_front(const T& x)
{
    insert(begin(), x);
}

void insert(iterator pos, const T& x)
{
    node* cur = pos._node;
    node* prev = cur->_prev;

    node* new_node = new node(x);

    prev->_next = new_node;
    new_node->_prev = prev;
    new_node->_next = cur;
    cur->_prev = new_node;
}

iterator erase(iterator pos)
{
    assert(pos != end());
    //头节点不能删

    node* prev = pos._node->_prev;
    node* next = pos._node->_next;

    prev->_next = next;
    next->_prev = prev;

    delete pos._node;

    //删除节点后,返回后一个节点迭代器
    return iterator(next);
}

void clear()
{
    iterator it = begin();
    while (it != end())
    {
        erase(it++);
    }
}

void pop_back()
{
    erase(--end);
}
void pop_front()
{
    erase(begin());
}

list的迭代器失效

cpp 复制代码
void TestListIterator1()
{
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    list<int> l(array, array + sizeof(array) / sizeof(array[0]));
    auto it = l.begin();
    while (it != l.end())
    {
        // erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给其赋值
        l.erase(it);
        ++it;
    }
}
// 改正
void TestListIterator()
{
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    list<int> l(array, array + sizeof(array) / sizeof(array[0]));
    auto it = l.begin();
    while (it != l.end())
    {
        l.erase(it++); // it = l.erase(it);
    }
}
相关推荐
akinggw1 小时前
libagentcore - 一个基于c++的AI多agent系统升级到2.0版本
开发语言·jvm·c++
繁星蓝雨2 小时前
C++设计原理———多重继承(虚基类、菱形继承、委托、重命名、基类和成员初始化)
c++·委托·多重继承·mi·显式初始化列·虚基类·对象布局
旖旎夜光2 小时前
【C++ 基础入门】命名空间、输入输出、缺省参数与函数重载
开发语言·c++·笔记·学习
扶尔魔ocy3 小时前
【QT入门到晋级】用开源的自定义控件开发
c++·qt·自定义控件
akinggw4 小时前
libsherpacore - 基于 sherpa-onnx 的 C++ 语音交互静态库
c++·交互·语音识别
xiaoye-duck4 小时前
《C++ 项目:手写大模型接入 SDK》ChatGPT接口设计(中):全量响应实现和测试
网络·c++·语言模型·chatgpt
東隅已逝,桑榆非晚5 小时前
算法3.双指针法-快乐数
c++·笔记·学习·算法
eggwyw6 小时前
C++相交链表和反转链表详解
开发语言·c++
杜 硕6 小时前
从零开始的C++生活——第六讲——02
c++·算法·生活
小超人诞生日记6 小时前
C++ STL 反向迭代器:从源码框架到适配器实现
c++·算法