【手撕】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);
    }
}
相关推荐
刃神太酷啦19 分钟前
数据结构(蓝桥杯常考点)
数据结构·c++·蓝桥杯c++组
17´30 分钟前
Qt从入门到入土(八) -打包Qt程序
开发语言·c++·qt
誓约酱1 小时前
(每日一题) 力扣 860 柠檬水找零
linux·c语言·c++·算法·leetcode·职场和发展
城西往事1 小时前
DeepSeek 解释C语言函数memset
c++
孞㐑¥2 小时前
C++vector类
开发语言·c++·经验分享·笔记
chenyuhao20243 小时前
非常重要的动态内存错误和柔性数组1
c语言·c++·算法·柔性数组
坚定学代码4 小时前
Qt C++ 实际开发中宏编译的运用
c++·qt
香菇滑稽之谈4 小时前
装饰器模式的C++实现示例
c++·算法·设计模式·装饰器模式
小赵起名困难户4 小时前
蓝桥杯备赛-差分-重新排序
c++·算法·蓝桥杯
牵牛老人4 小时前
C++设计模式-简单工厂模式:从原理、应用、实践指南与常见问题和解决方案深度解析
c++·设计模式·简单工厂模式