【手撕】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);
    }
}
相关推荐
草原上唱山歌43 分钟前
C++需要学习哪些内容?
开发语言·c++·学习
Clrove.111 小时前
C++初阶——queue
开发语言·c++
hunandede1 小时前
FFmpeg 4.3 音视频-多路H265监控录放C++开发十三.3:将AVFrame转换成AVPacket.封装。代码改动
c++·ffmpeg·音视频
找不着地窖的皮险家1 小时前
ROS Action
c++·机器人·ros
写bug的小屁孩1 小时前
基于HTTP编写ping操作
服务器·c语言·网络·c++·网络协议·http·qt6.3
摆烂小白敲代码2 小时前
【机器学习】K近邻算法
c++·人工智能·算法·机器学习·近邻算法
Padid2 小时前
SRP 实现 Cook-Torrance BRDF
c++·笔记·unity·游戏程序·图形渲染·着色器
Vec[95]2 小时前
Opengl光照测试
c++·数码相机·算法
孤寂码农_defector2 小时前
C++清除所有输出【DEV-C++】所有编辑器通用 | 算法基础NO.1
数据结构·c++·算法·编辑器
oioihoii2 小时前
设计模式概述
java·c++·设计模式·面试·c#·大学必学