【手撕】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);
    }
}
相关推荐
感哥9 小时前
C++ 面向对象
c++
沐怡旸11 小时前
【底层机制】std::shared_ptr解决的痛点?是什么?如何实现?如何正确用?
c++·面试
感哥17 小时前
C++ STL 常用算法
c++
saltymilk1 天前
C++ 模板参数推导问题小记(模板类的模板构造函数)
c++·模板元编程
感哥1 天前
C++ lambda 匿名函数
c++
沐怡旸1 天前
【底层机制】std::unique_ptr 解决的痛点?是什么?如何实现?怎么正确使用?
c++·面试
感哥1 天前
C++ 内存管理
c++
博笙困了2 天前
AcWing学习——双指针算法
c++·算法
感哥2 天前
C++ 指针和引用
c++
感哥2 天前
C++ 多态
c++