wordpress博客网站描述在哪里,百度站长快速收录,西宁网站建设制作公司,先进网站【C】“list”的介绍和常用接口的模拟实现 一. list的介绍1. list常见的重要接口2. list的迭代器失效 二. list常用接口的模拟实现#xff08;含注释#xff09;三. list与vector的对比 一. list的介绍
list是可以在常数范围内在任意位置进行插入和删除的序列式容器#xf… 【C】“list”的介绍和常用接口的模拟实现 一. list的介绍1. list常见的重要接口2. list的迭代器失效 二. list常用接口的模拟实现含注释三. list与vector的对比 一. list的介绍
list是可以在常数范围内在任意位置进行插入和删除的序列式容器并且该容器可以前后双向迭代。list的底层是双向带头链表结构双向链表中每个元素存储在互不相关的独立节点中在节点中通过指针指向其前一个元素和后一个元素。list与forward_list非常相似最主要的不同在于forward_list是单链表只能朝前迭代已让其更简单高效。与其他的序列式容器相比(arrayvectordeque)list通常在任意位置进行插入、移除元素的执行效率更好。与其他序列式容器相比list和forward_list最大的缺陷是不支持任意位置的随机访问比如要访问list的第6个元素必须从已知的位置(比如头部或者尾部)迭代到该位置在这段位置上迭代需要线性的时间开销list还需要一些额外的空间以保存每个节点的相关联信息。 1. list常见的重要接口 begin与end为正向迭代器对迭代器执行操作迭代器向后移动rbegin(end)与rend(begin)为反向迭代器对迭代器执行操作迭代器向前移动 2. list的迭代器失效 迭代器失效即迭代器所指向的节点的无效即该节点被删除了。因为list的底层结构为带头结点的双向循环链表因此在list中进行插入时是不会导致list的迭代器失效的只有在删除时才会失效并且失效的只是指向被删除节点的迭代器其他迭代器不会受到影响 二. list常用接口的模拟实现含注释
#includeassert.h
#includeiostream
using std::cout;
using std::endl;
namespace wch
{//由于list中的val支持多种类型定义模板参数Ttemplateclass Tstruct list_node{list_nodeT* _next;list_nodeT* _prev;T _val;//T(),针对自定义类型会去调用它的构造函数针对内置类型无影响list_node(const T val T()):_next(nullptr), _prev(nullptr), _val(val){}};// typedef __list_iteratorT, T, T* iterator;// typedef __list_iteratorT, const T, const T* const_iterator;//此处定义多个模板参数针对返回值类型templateclass T, class Ref, class Ptrstruct __list_iterator{typedef list_nodeT Node;typedef __list_iteratorT, Ref, Ptr self;Node* _node;__list_iterator(Node* node):_node(node){}Ref operator*() const//重载普通对象解引用{return _node-_val;}Ptr operator-() const//重载指针对象解引用{return _node-_val;}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;}//尽量使用引用形参 避免拷贝开销。同时在不需要修改实参时通过指定const 引用形参来限制。bool operator!(const self it) const{return _node ! it._node;}bool operator(const self it) const{return _node it._node;}};templateclass Tclass list{typedef list_nodeT Node;public:typedef __list_iteratorT, T, T* iterator;typedef __list_iteratorT, const T, const T* const_iterator;// 这样设计const迭代器是不行的因为const迭代器期望指向内容不能修改// 这样设计是迭代器本身不能修改// T* const ptr2;iterator begin() {//return _head-_next;//单参构造函数支持隐式类型转换return iterator(_head-_next);}iterator end() {return _head;//单参构造函数支持隐式类型转换//return iterator(_head);}const_iterator begin() const{//return _head-_next;return const_iterator(_head-_next);}const_iterator end() const{return _head;//return const_iterator(_head);}void empty_init(){_head new Node;_head-_prev _head;_head-_next _head;_size 0;}list()//无参默认构造函数{empty_init();}// lt2(lt1)list(const listT lt)//拷贝构造//list(const list lt)//不加类型也可以不建议{empty_init();for (auto e : lt)//深拷贝{push_back(e);}}void swap(listT lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}listT operator(listT lt)//赋值运算符重载//list operator(list lt)//不加类型也可以不建议{swap(lt);return *this;}~list()//析构函数{clear();delete _head;_head nullptr;}void clear(){iterator it begin();while (it ! end()){it erase(it);//带位置返回值的erase函数防止迭代器失效}_size 0;}void push_back(const T x){insert(end(), x);}void push_front(const T x){insert(begin(), x);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}// pos位置之前插入iterator insert(iterator pos, const T x){Node* cur pos._node;Node* prev cur-_prev;Node* newnode new Node(x);prev-_next newnode;newnode-_next cur;cur-_prev newnode;newnode-_prev prev;_size;return newnode;}//删除pos处节点iterator erase(iterator pos){assert(pos ! end());//不可删除头节点Node* cur pos._node;Node* prev cur-_prev;Node* next cur-_next;prev-_next next;next-_prev prev;delete cur;--_size;return next;}size_t size(){/*size_t sz 0;iterator it begin();while (it ! end()){sz;it;}return sz;*/return _size;}private:Node* _head;size_t _size;};void Print(const listint lt){listint::const_iterator it lt.begin();while (it ! lt.end()){//(*it) 1;cout *it ;it;}cout endl;}void test_list1(){listint lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);listint::iterator it lt.begin();//由于链表的各个节点地址是不连续的前一个节点的地址可能比后一个地址大所以不可已写为 it it.end();while (it ! lt.end()){(*it) 1;cout *it ;it;}cout endl;for (auto e : lt){cout e ;}cout endl;Print(lt);}struct A{A(int a1 0, int a2 0):_a1(a1), _a2(a2){}int _a1;int _a2;};void test_list2(){listA lt;lt.push_back(A(1, 1));lt.push_back(A(2, 2));lt.push_back(A(3, 3));lt.push_back(A(4, 4));listA::iterator it lt.begin();while (it ! lt.end()){//cout (*it)._a1 (*it)._a2 endl;//it--_a1, it--_a2,特殊处理为一个-cout it-_a1 it-_a2 endl;it;}cout endl;}void test_list3(){listint lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_front(5);lt.push_front(6);lt.push_front(7);lt.push_front(8);for (auto e : lt){cout e ;}cout endl;lt.pop_front();lt.pop_back();for (auto e : lt){cout e ;}cout endl;lt.clear();lt.push_back(10);lt.push_back(20);lt.push_back(30);lt.push_back(40);for (auto e : lt){cout e ;}cout endl;cout lt.size() endl;}void test_list4(){listint lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);for (auto e : lt){cout e ;}cout endl;listint lt1(lt);for (auto e : lt1){cout e ;}cout endl;listint lt2;lt2.push_back(5);lt2.push_back(6);lt2.push_back(7);lt2.push_back(8);for (auto e : lt2){cout e ;}cout endl;lt1 lt2;for (auto e : lt1){cout e ;}cout endl;}
}三. list与vector的对比
vector与list都是STL中非常重要的序列式容器由于两个容器的底层结构不同导致其特性以及应用场景不同其主要不同如下