赞
踩
主页:醋溜马桶圈-CSDN博客
目录
list - C++ Reference (cplusplus.com)
- list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代
- list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素
- list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效
- 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好
- 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)
list中的接口比较多,此处类似,只需要掌握如何正确的使用,然后再去深入研究背后的原理,已达到可扩展的能力。以下为list中一些常见的重要接口
此处,大家可暂时将迭代器理解成一个指针,该指针指向list中的某个节点
【注意】
- list<int> lt;
- lt.push_back(1);
- lt.push_back(2);
- lt.push_back(3);
- lt.push_back(4);
- lt.push_back(4);
- lt.push_back(4);
- lt.push_back(4);
前面说过,此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响
- #pragma once
- #include <assert.h>
- #include <iostream>
- using namespace std;
-
- namespace dc
- {
- template<class T>
- struct ListNode
- {
- ListNode<T>* _next;
- ListNode<T>* _prev;
- T _data;
-
- ListNode(const T& x=T())
- :_next(nullptr)
- ,_prev(nullptr)
- ,_data(x)
- {}
- };
- //typedef ListIterator<T, T&, T*> iterator;
- //typedef ListIterator<T, const T&, const T*> const_iterator;
- template<class T,class Ref,class Ptr>
- struct ListIterator
- {
- typedef ListNode<T> Node;
- typedef ListIterator<T, Ref, Ptr> Self;
-
- Node* _node;
-
- ListIterator(Node* node)
- :_node(node)
- {}
- //*it
- //T& operator*()
- Ref operator*()
- {
- return _node->_data;
- }
- //it->
- //T* operator->()
- Ptr operator->()
- {
- return &_node->_data;
- }
- //++it
- Self& operator++()
- {
- _node = _node->_next;
- return *this;
- }
- //it++
- Self operator++(int)
- {
- Self tmp(*this);
- _node = _node->_next;
- return tmp;
- }
- //--it
- Self& operator--()
- {
- _node = _node->_prev;
- return *this;
- }
- //it--
- Self operator--(int)
- {
- Self tmp(*this);
- _node = _node->_prev;
- return tmp;
- }
- bool operator!=(const Self& it)
- {
- return _node != it._node;
- }
- bool operator==(const Self& it)
- {
- return _node == it._node;
- }
- };
-
- //template<class T>
- //struct ListConstIterator
- //{
- // typedef ListNode<T> Node;
- // typedef ListConstIterator<T> Self;
- // Node* _node;
- // ListConstIterator(Node* node)
- // :_node(node)
- // {}
- // //*it
- // const T& operator*()
- // {
- // return _node->_data;
- // }
- // //it->
- // const T* operator->()
- // {
- // return &_node->_data;
- // }
- // //++it
- // Self& operator++()
- // {
- // _node = _node->_next;
- // return *this;
- // }
- // //it++
- // Self operator++(int)
- // {
- // Self tmp(*this);
- // _node = _node->_next;
- // return tmp;
- // }
- // //--it
- // Self& operator--()
- // {
- // _node = _node->_prev;
- // return *this;
- // }
- // //it--
- // Self operator--(int)
- // {
- // Self tmp(*this);
- // _node = _node->_prev;
- // return tmp;
- // }
- // bool operator!=(const Self& it)
- // {
- // return _node != it._node;
- // }
- // bool operator==(const Self& it)
- // {
- // return _node == it._node;
- // }
- //};
-
- template<class T>
- class list
- {
- typedef ListNode<T> Node;
- public:
- //typedef ListIterator<T> iterator;
- //typedef ListConstIterator<T> const_iterator;
- typedef ListIterator<T, T&, T*> iterator;
- typedef ListIterator<T, const T&, const T*> const_iterator;
-
- iterator begin()
- {
- //return _head->_next;
-
- return _head->_next;
- }
- iterator end()
- {
- return _head;
- }
-
- const_iterator begin() const
- {
- //return _head->_next;
-
- return _head->_next;
- }
- const_iterator end() const
- {
- return _head;
- }
- //初始化头结点
- void empty_init()
- {
- _head = new Node;
- _head->_next = _head;
- _head->_prev = _head;
- _size = 0;
- }
- list()
- {
- empty_init();
- }
- //lt2(lt1)
- list(const list<T>& lt)
- {
- empty_init();
- for (auto& e : lt)
- {
- push_back(e);
- }
- }
- //需要析构,一般就需要自己写深拷贝
- //不需要析构,默认浅拷贝就可以
- void swap(list<T>& lt)
- {
- std::swap(_head, lt._head);
- std::swap(_size, lt._size);
- }
- //lt1=lt3
- list<T>& operator=(list<T> lt)
- {
- swap(lt);
- return *this;
- }
- void clear()
- {
- iterator it = begin();
- while (it != end())
- {
- it = erase(it);
- }
- }
- ~list()
- {
- clear();
- delete _head;
- _head = nullptr;
- }
- //void push_back(const T& x)
- //{
- // Node* newnode = new Node(x);
- // Node* tail = _head->_prev;
- // tail->_next = newnode;
- // newnode->_prev = tail;
- // _head->_prev = newnode;
- // newnode->_next = _head;
- //}
- 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());
- }
- void insert(iterator pos, const T& val)
- {
- Node* cur = pos._node;
- Node* newnode = new Node(val);
- Node* prev = cur->_prev;
- prev->_next = newnode;
- newnode->_next = cur;
- cur->_prev = newnode;
- newnode->_prev = prev;
- _size++;
- }
- iterator erase(iterator pos)
- {
- Node* cur = pos._node;
- Node* prev = cur->_prev;
- Node* next = cur->_next;
- prev->_next = next;
- next->_prev = prev;
- delete cur;
- _size--;
- return iterator(next);
- }
- size_t size() const
- {
- return _size;
- }
- bool empty()
- {
- return _size == 0;
- }
-
-
- private:
- Node* _head;
- size_t _size;
- };
- }
通过前面例子知道,反向迭代器的++就是正向迭代器的--,反向迭代器的--就是正向迭代器的++,因此反向迭代器的实现可以借助正向迭代器,即:反向迭代器内部可以包含一个正向迭代器,对正向迭代器的接口进行包装即可
- template<class Iterator>
- class ReverseListIterator
- {
- // 注意:此处typename的作用是明确告诉编译器,Ref是Iterator类中的类型,而不是静态成员变量
- // 否则编译器编译时就不知道Ref是Iterator中的类型还是静态成员变量
- // 因为静态成员变量也是按照 类名::静态成员变量名 的方式访问的
- public:
- typedef typename Iterator::Ref Ref;
- typedef typename Iterator::Ptr Ptr;
- typedef ReverseListIterator<Iterator> Self;
- public:
- //
- // 构造
- ReverseListIterator(Iterator it) : _it(it) {}
- //
- // 具有指针类似行为
- Ref operator*() {
- Iterator temp(_it);
- --temp;
- return *temp;
- }
- Ptr operator->() { return &(operator*()); }
- //
- // 迭代器支持移动
- Self& operator++() {
- --_it;
- return *this;
- }
- Self operator++(int) {
- Self temp(*this);
- --_it;
- return temp;
- }
- Self& operator--() {
- ++_it;
- return *this;
- }
- Self operator--(int)
- {
- Self temp(*this);
- ++_it;
- return temp;
- }
- //
- // 迭代器支持比较
- bool operator!=(const Self& l)const { return _it != l._it; }
- bool operator==(const Self& l)const { return _it != l._it; }
- Iterator _it;
- };
vector与list都是STL中非常重要的序列式容器,由于两个容器的底层结构不同,导致其特性以及应用场景不 同,其主要不同如下
- void test2()
- {
- srand(time(0));
- const int N = 1000000;
- list<int> lt1;
- list<int> lt2;
- vector<int> v;
- for (int i = 0; i < N; i++)
- {
- auto e = rand()+i;
- lt1.push_back(e);
- v.push_back(e);
- }
- int begin1 = clock();
- //排序
- sort(v.begin(), v.end());
- int end1 = clock();
-
- int begin2 = clock();
- lt1.sort();
- int end2 = clock();
- printf("vector sort:%d\n", end1 - begin1);
- printf("list sort:%d\n", end2 - begin2);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。