目录
list的介绍:
list的构造:
遍历:
reverse、sort、unique
list的模拟实现:
反向迭代器:
list与vector的比较:
list的介绍:
list是序列容器,允许在序列内的任何位置执行O(1)的插入和删除操作,以及双向迭代。

list的构造:
void TestList1()
{
    list<int> l1;                         // 构造空的l1
    list<int> l2(4, 10);                  // 4个10
    list<int> l3(l2.begin(), l2.end());   // 用l2的[begin(), end())构造l3
    list<int> l4(l3);                     // 用l3拷贝构造l4
    // 以数组为迭代器区间构造l5
    int arr[] = { 16,2,77,29 };
    list<int> l5(arr, arr + sizeof(arr) / sizeof(int));
    // 列表格式初始化C++11
    list<int> l6{ 1, 2, 3, 4, 5 };
}遍历:
list只能通过迭代器和范围for进行遍历,不支持下标访问。
void test_list2()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	list<int>::iterator it = lt.begin();
	while (it != lt.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	list<int>::reverse_iterator rit = lt.rbegin();
	while (rit != lt.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;
}reverse、sort、unique(有序,去重)
void test_list2()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(3);
	lt.push_back(3);
	lt.push_back(2);
	lt.push_back(4);
	lt.sort();                //排序
	lt.reverse();            //逆置
	lt.unique();            //去重(有序)
}list的模拟实现:
List 的迭代器是将原生指针进行封装,把节点指针放到迭代器类中,对迭代器类进行运算符重载,就可以像顺序容器的指针一样进行访问和修改
namespace qwe
{
	template<class T>
	struct ListNode
	{
		ListNode<T>* _next;
		ListNode<T>* _prev;
		T _data;
		ListNode(const T& data = T())
			:_next(nullptr)
			, _prev(nullptr)
			, _data(data)
		{}
	};
	          //   T         T&        T*
	template<class T, class Ref, class Ptr>
	struct __list_iterator
	{
		typedef ListNode<T> Node;
		typedef __list_iterator<T, Ref, Ptr> self;
		Node* _node;
		__list_iterator(Node* x)
			:_node(x)
		{}
		Ref operator*()
		{
			return _node->_data;
		}
		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)const
		{
			return _node != it._node;
		}
		bool operator==(const self& it)const
		{
			return _node == it._node;
		}
	};
	template<class T>
	class list
	{
		typedef ListNode<T> Node;
	public:
		typedef __list_iterator<T, T&, T*> iterator;
		typedef __list_iterator<T, const T&, const T*> const_iterator;
		typedef reverse_iterator<const_iterator, const T&, const T* > const_reverse_iterator;
		typedef reverse_iterator<iterator, T&, T*> reverse_iterator;
		reverse_iterator rbegin()
		{
			return reverse_iterator(end());
		}
		reverse_iterator rend()
		{
			return reverse_iterator(begin());
		}
		iterator begin()
		{
			return iterator(_head->_next);
		}
		iterator end()
		{
			return iterator(_head);
		}
		const_iterator begin()const
		{
			return const_iterator(_head->_next);
		}
		const_iterator end()const
		{
			return const_iterator(_head);
		}
		list()
		{
			_head = new Node();
			_head->_next = _head;
			_head->_prev = _head;
		}
		//list<Date> lt1(5, Date(2022, 1, 11));
		//list<int> lt2(5, 1)
		list(int n, const T& val = T())
		{
			_head = new Node();
			_head->_next = _head;
			_head->_prev = _head;
			for (int i = 0; i < n; ++i)
			{
				push_back(val);
			}
		}
		list(size_t n, const T& val = T())
		{
			_head = new Node();
			_head->_next = _head;
			_head->_prev = _head;
			for (size_t i = 0; i < n; ++i)
			{
				push_back(val);
			}
		}
		template<class InputIterator>
		list(InputIterator first, InputIterator last)
		{
			_head = new Node();
			_head->_next = _head;
			_head->_prev = _head;
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}
		//lt2(lt1)
		list(const list<T>& lt)
		{
			_head = new Node();
			_head->_next = _head;
			_head->_prev = _head;
			list<T> tmp(lt.begin(), lt.end());
			std::swap(_head, tmp._head);
		}
		//lt2 = lt1
		list<T>& operator=(list<T> lt)
		{
			std::swap(_head, lt._head);
			return *this;
		}
		~list()
		{
			clear();
			delete _head;
			_head = nullptr;
		}
		void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				erase(it++);
			}
		}
		void push_front(const T& x)
		{
			insert(begin(), x);
		}
		void push_back(const T& x)
		{
			insert(end(), x);
		}
		void pop_back()
		{
			erase(--end());
		}
		void pop_front()
		{
			erase(begin());
		}
		//insert,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->_prev = prev;
			newnode->_next = cur;
			cur->_prev = newnode;
			return iterator(newnode);
		}
		//erase,pos一定失效
		iterator erase(iterator pos)
		{
			assert(pos != end());
			Node* prev = pos._node->_prev;
			Node* next = pos._node->_next;
			delete pos._node;
			prev->_next = next;
			next->_prev = prev;
			return iterator(next);
		}
	private:
		Node* _head;
	};
	void print_list(const list<int>& lt)
	{
		list<int>::const_iterator it = lt.begin();
		while (it != lt.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
	}
	void test_list1()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);
		list<int>::iterator it = lt.begin();
		while (it != lt.end())
		{
			*it *= 2;
			cout << *it << " ";
			++it;
		}
		cout << endl;
		print_list(lt);
	}
	struct Date
	{
		int _year;
		int _month;
		int _day;
		Date(int year = 1, int month = 1, int day = 1)
			:_year(year)
			, _month(month)
			, _day(day)
		{}
	};
	void test_list2()
	{
		list<Date> lt;
		lt.push_back(Date(2001, 1, 11));
		lt.push_back(Date(2001, 2, 11));
		lt.push_back(Date(2001, 3, 11));
		list<Date>::iterator it = lt.begin();
		while (it != lt.end())
		{
			cout << (*it)._year << " ";
			cout << it->_year << " ";
			++it;
		}
		cout << endl;
	}
	void test_list3()
	{
		list<int> lt1;
		lt1.push_back(1);
		lt1.push_back(2);
		lt1.push_back(3);
		list<int> lt2(lt1);
		for (auto e : lt2)
		{
			cout << e << " ";
		}
		cout << endl;
		list<int> lt3;
		lt3.push_back(10);
		lt3.push_back(10);
		lt3.push_back(10);
		lt3.push_back(10);
		lt1 = lt3;
		for (auto e : lt1)
		{
			cout << e << " ";
		}
		cout << endl;
	}
	void test_list4()
	{
		list<Date> lt1(5, Date(2022, 1, 1));
		for (auto e : lt1)
		{
			cout << e._year << " ";
		}
		cout << endl;
		list<int> lt2(5, 1);
		for (auto e : lt2)
		{
			cout << e << " ";
		}
		cout << endl;
	}
	void test_list5()
	{
		list<int> lt1;
		lt1.push_back(1);
		lt1.push_back(2);
		lt1.push_back(3);
		lt1.push_back(4);
		list<int>::iterator it = lt1.begin();
		while (it != lt1.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
		list<int>::reverse_iterator rit = lt1.rbegin();
		while (rit != lt1.rend())
		{
			cout << *rit << " ";
			++rit;
		}
		cout << endl;
	}
}反向迭代器:
         反向迭代器的++就是正向迭代器的--,所以,反向迭代器内部可以包含一个正向迭代器,对正向迭代器的接口进行包装即可。
 
namespace qwe
{
	template<class Iterator, class Ref, class Ptr>
	class reverse_iterator
	{
		typedef reverse_iterator<Iterator, Ref, Ptr>self;
	public:
		reverse_iterator(Iterator it)
			:_it(it)
		{}
		Ref operator*()
		{
			Iterator prev = _it;
			return *--prev;
		}
		Ptr operator->()
		{
			return &operator*();
		}
		self& operator++()
		{
			--_it;
			return *this;
		}
		self& operator--()
		{
			++_it;
			return *this;
		}
		bool operator!=(const self& rit)const
		{
			return _it != rit._it;
		}
	private:
		Iterator _it;
	};
}list与vector的比较:
| vector | list | |
| 
     底 层 结 构
     | 
     动态顺序表,一段连续的物理空间 
     | 
     带头结点的双向循环链表 
     | 
| 随机访问 | 
     支持随机访问,访问某个元素效率O(1) 
     | 
     不支持随机访问,访问某个元素 
     
     效率O(N)
     | 
| 插入和删除 | 
     任意位置插入和删除效率低,时间复杂 度O(N),插入时有可能需要增容,增容:开辟新空间,拷贝元素,释放旧空间,导致效率更低 
     | 
     任意位置插入和删除效率高,时间复杂度为 O(1) 
     | 
| 空间利用率 | 
     底层为连续空间,不容易造成内存碎片,空间利用率 高,缓存命中率高 
     | 
     底层节点动态开辟,小节点容易 
     
     造成内存碎片,空间利用率低, 
     
     缓存命中率低 
     | 
| 迭代器 | 
     原生指针 
     | 
     对节点指针进行封装 
     | 
| 迭代器失效 | 
     插入元素有可能会导致重新扩容,致使原来迭代器失效,删除时,如果不考虑缩容,原来迭代器指向的内容改变导致失效
     | 
     插入元素不会导致迭代器失效, 
     
     删除元素时,只会导致当前迭代 
     
     器失效,其他迭代器不受影响 
     | 
| 使用场景 | 
     需要高效存储,支持随机访问,不关心插入删除效率 
     | 
     大量插入和删除操作,不关心随 
     
     机访问
     | 



















