目录
list基本介绍和使用
list - 带头双向循环链表。
对比vector,因为list是由一个个结点连接而成的,致使list
1. 不支持元素的随机访问,即没有operator[],因为效率低。访问元素front back
2. 没有capacity的概念,内存允许的情况下,可以无限申请节点并扩展
3. 支持push_front pop_front,使得list可以作为queue的适配容器
4. 最大的优势是在任意位置插入删除都可以在O(1)时间完成
学习成员函数 见https://cplusplus.com/reference/list/list/
list模拟实现
#ifndef STL_LIST_H
#define STL_LIST_H
#include <cstddef> // size_t
#include <cassert>
#include <iostream>
#include "reverse_iterator.h"
//using namespace std;
namespace yzl
{
template<class T>
struct list_node // list内部使用的结点类型
{
public:
T _data;
list_node<T>* _next;
list_node<T>* _prev;
public:
list_node(const T& data = T()) // 结点的默认构造函数
: _data(data), _next(nullptr), _prev(nullptr)
{ }
// ~list_node() = default;
// // 拷贝构造,其实没必要
// list_node(const list_node<T>& node)
// : _data(node._data), _next(node._next), _prev(node._prev) // 浅拷贝
// { }
// // 赋值运算符重载,也没必要
// list_node<T>& operator=(const list_node<T>& node) // 浅拷贝
// {
// _data = node._data;
// _prev = node._prev;
// _next = node._next;
// return *this;
// }
};
// 说真的,只是对结点指针的一个封装罢了,构造函数也是通过一个结点指针即可构造出一个迭代器。
// 对于迭代器的操作,其实也就是++ -- 然后解引用。目前的操作就是这些,之后再有再补充吧。
template<class T, class Ref, class Ptr> // T& T* or const T& const T*
class __list_iterator // 成员就是一个结点指针
{
public:
typedef list_node<T> Node; // 这是一个结构体,结点。Node就是一个结点结构体。
typedef __list_iterator<T, Ref, Ptr> iterator;
typedef std::bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef ptrdiff_t difference_type;
public:
Node* _node; // 这个迭代器类型有一个数据成员,是结点指针。
public:
__list_iterator(Node* node)
:_node(node)
{ }
// 这个类型的实例化对象本身不支持解引用操作,operator*赋予了它解引用之后的操作。
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &(operator*());
// return &(_node->_data);
}
bool operator!=(const iterator& it)
{
return _node != it._node;
}
bool operator==(const iterator& it)
{
return _node == it._node;
}
// 思考一下迭代器++,普通迭代器和const迭代器其实都可以++
iterator& operator++() // 前置
{
_node = _node->_next;
return *this;
}
iterator operator++(int) // 后置
{
iterator tmp = *this;
this->_node = this->_node->_next;
return tmp;
}
iterator& operator--()
{
_node = _node->_prev;
return *this;
}
iterator operator--(int)
{
iterator tmp(*this);
this->_node = this->_node->_prev;
return tmp;
}
};
// list<int> ls;
template<class T>
class list
{
private:
typedef list_node<T> Node;
Node* _head; // list_node<int>* _head;
public:
// 说真的,关于list的迭代器,你只需要实现begin end这一系列的即可,还要让它的返回值支持++ 解引用操作,这就够了,说真的。
typedef __list_iterator<T, T&, T*> iterator; // 这个结构体别名为迭代器,本身是不支持解引用操作的。
//typedef const __list_iterator<T> const_iterator; // 你这里const修饰的是迭代器类型,他有结点指针数据成员,const使得结点指针不能改变。
// 但是根本上,const迭代器是指不能修改*迭代器所指的值。而不是迭代器本身。
typedef __list_iterator<T, const T&, const T*> const_iterator;
// typedef __list_reverse_iterator<T, T&, T*> reverse_iterator;
// typedef __list_reverse_iterator<T, const T&, const T*> const_reverse_iterator;
typedef __reverse_iterator<__list_iterator<T, T&, T*>, T&, T*> reverse_iterator;
typedef __reverse_iterator<const_iterator, const T&, const T*> const_rever

本文介绍了C++ STL中的list容器,包括其基本操作、模拟实现以及迭代器的工作原理。重点讨论了list的迭代器实现,包括const_iterator的问题和反向迭代器的设计,强调了list在插入删除操作上的高效性,并对比了list与vector的区别。
最低0.47元/天 解锁文章
1479

被折叠的 条评论
为什么被折叠?



