cpp
              
              
            
          
          iterator insert(iterator pos,const T&x)
{
	Node* newnode = new Node(x);
	Node* cur = pos._node;//先存一下pos位置的指针
	Node* prev = cur->_prev;//再存一下没插入之前pos前面节点的指针
	cur->_prev = newnode;
	newnode->_next = cur;
	newnode->_prev = prev;
	prev->_next = newnode;
	
	return newnode;
}
        开头
            
            
              cpp
              
              
            
          
          #include<iostream>
#include<assert.h>
using namespace std;
namespace Ljw
        //结点,节点要要公开,用struct就好
            
            
              cpp
              
              
            
          
          //结点,节点要要公开,用struct就好
template<class T>
struct list_node
{
	list_node<T>* _prev;
	list_node<T>* _next;
	T _val;
	//结点的初始化构造函数
	list_node(const T&val=T())//写成T(),是为了防止T不是内置类型
		:_val(val)
		,_prev(nullptr)
		,_next(nullptr)
	{}
};
        迭代器指针
            
            
              cpp
              
              
            
          
          template<class T, class  Ref,   class Ptr>
struct __list_node
{
    typedef list_node<T> Node;
    typedef __list_node<T,Ref,Ptr>  KKK;
};
        指向节点的指针
            
            
              cpp
              
              
            
          
          Node* _node;
        构造函数
            
            
              cpp
              
              
            
          
          __list_node(Node*node)
	:_node(node)
{}
        operator*
            
            
              cpp
              
              
            
          
          Ref& operator*()//这里是const迭代器的关键,返回的*it,就是指向的位置
{
	return _node->_val;
}
        这里是const迭代器的关键,返回的*it,就是指向的位置
operator++
            
            
              cpp
              
              
            
          
          	KKK operator++()
	{
		_node = _node->_next;
		return *this;
	}
    KKK operator++(int)
    {
	    KKK tmp(*this);
	    _node = _node->_next;
	    return tmp;
    }
        operator--
            
            
              cpp
              
              
            
          
          KKK operator--()
{
	_node = _node->_prev;
	return *this;
}	
KKK operator--(int)
{
	Node tmp(*this);
	_node = _node->_prev;
	return tmp;
}
        operator!=
            
            
              cpp
              
              
            
          
          bool operator!=(const KKK&it)//里面必须加const,因为返回的end()具有常性
{
	return _node != it._node;
}
        里面必须加const,因为返回的end()具有常性
operator->
            
            
              cpp
              
              
            
          
          Ptr* operator->()//这里的T*也分为const和不带const,所以加上class Ptr
{
	return &_node->_val;
}
        这里的T*也分为const和不带const,所以加上class Ptr
list
            
            
              cpp
              
              
            
          
          template<class T>
class list
{
private:
	Node*_head;
	size_t _size;
};
        三参数的传递
(第二个const迭代器,第三个是带不带const的->的重载)
            
            
              cpp
              
              
            
          
          	typedef list_node<T> Node;//相当于私有
public:
	//迭代器
	typedef __list_node<T,T&, T*>  iterator;//第三个T*是为了operator->的重载
	//const迭代器
	//typedef const __list_node<T>  const_iterator;这种写法是错误的,因为const后的对象无法
	                                                                             //修改,但我们需要的是it++,可以被修改,不被修改的是
														//指向的内容不被修改
														
	//正确写法
	typedef __list_node<T,const T&,const T*>  const_iterator;
        //const迭代器
//typedef const __list_node<T> const_iterator;这种写法是错误的,因为const后的对象无法修改,但我们需要的是it++,可以被修改,不被修改的是指向的内容不被修改
构造函数
            
            
              cpp
              
              
            
          
          list()
{
	_head = new Node;// new一个类型就相当于new一个这个类型的空间
	_head->_next = _head;
	_head->_prev = _head;
}
        new一个类型就相当于new一个这个类型的空间
尾插
            
            
              cpp
              
              
            
          
          void push_back(const T&x)
{
	//Node* newnode = new Node(x);//初始化为x,()是初始化[]开空间
	先把尾结点和头结点连接起来
	//Node* tail = _head->_prev;//一开始时,_head_>prev指向的是自己
	//tail->_next = newnode;//一开始要把_head的prev和next与newnode连接起来
	//newnode->_prev = tail;
	//newnode->_next = _head;
	//_head->_prev = newnode;
	insert(end(),x);
}
        iterator begin
            
            
              cpp
              
              
            
          
          iterator begin()
{
	return _head->_next;
}
        iterator end()
            
            
              cpp
              
              
            
          
          iterator end()
{
	return _head;//左闭右开
}
        const_iterator
            
            
              cpp
              
              
            
          
          const_iterator begin() const
{
	return _head->_next;
}
const_iterator end() const
{
	return _head;//左闭右开
}
        pos位置前插入
            
            
              cpp
              
              
            
          
          iterator insert(iterator pos,const T&x)
{
	Node* newnode = new Node(x);
	Node* cur = pos._node;//先存一下pos位置的指针
	Node* prev = cur->_prev;//再存一下没插入之前pos前面节点的指针
	cur->_prev = newnode;
	newnode->_next = cur;
	newnode->_prev = prev;
	prev->_next = newnode;
	
	return newnode;
}
        pos位置的删除
            
            
              cpp
              
              
            
          
          iterator erase(iterator pos)
{
	assert(pos != end());//不能删除头结点
	Node* cur = pos._node;//存一下pos的节点指针
	Node* prev = cur->_prev;//存一下pos之前节点的指针
	Node* next = cur->_next;//存一下pos下一个节点的指针
	//连接pos位置前一个和后一个的节点,然后释放pos的空间
	prev->_next = next;
	next->_prev = prev;
	
	delete[]  cur;//加不加[]都行
	return next;
}
        pop_back
            
            
              cpp
              
              
            
          
          void pop_back() 
{ 
	erase(--end()); 
}
        push_front
            
            
              cpp
              
              
            
          
          void push_front(const T& val) 
{ 
	insert(begin(), val); 
}
        pop_front
            
            
              cpp
              
              
            
          
          void pop_front() 
{ 
	erase(begin()); 
}
        size
            
            
              cpp
              
              
            
          
          size_t size()
{
	size_t i = 0;
	auto it = begin();
	while (it != end())
	{
		i++;
		it++;
	}
	return i;
}
        clear
clear,顺序表vector不需要释放空间,因为没法单独释放一部分空间,而链表list可以
            
            
              cpp
              
              
            
          
          void clear()
{
	auto it = begin();
	while (it != end())
	{
		it = erase(it);//这里会释放空间
		it++;
	}
	_size = 0;
}
        erase(it);//这里会释放空间
析构
            
            
              cpp
              
              
            
          
          ~list()
{
	clear();
	delete _head;
	_head = nullptr;
}
        拷贝构造
必须要有一个头结点
            
            
              cpp
              
              
            
          
          list(const list<T>& It)
{
	//必须要有一个头结点
	_head = new Node;
	_head->_next = _head;
	_head->_prev = _head;
	auto it = It.begin();
	while (it != It.end())
	{
		push_back(*it);
		it++;
	}
}
        swap
            
            
              cpp
              
              
            
          
          	void swap(list<T>&It)
	{
		std::swap(_head, It._head);
		std::swap(_size, It._size);
	}
        operator=
            
            
              cpp
              
              
            
          
          //=的实现
list<T>& operator=(list<T>&It)
{
	//现代写法用swap
	swap(It);
	return *this;
}
        总代码加测试
            
            
              cpp
              
              
            
          
          //list.h
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
namespace Ljw
{
	//结点,节点要要公开,用struct就好
	template<class T>
	struct list_node
	{
		list_node<T>* _prev;
		list_node<T>* _next;
		T _val;
		//结点的初始化构造函数
		list_node(const T&val=T())//写成T(),是为了防止T不是内置类型
			:_val(val)
			,_prev(nullptr)
			,_next(nullptr)
		{}
	};
	//迭代器指针
	template<class T, class  Ref,   class Ptr>
	struct __list_node
	{
		typedef list_node<T> Node;
		typedef __list_node<T,Ref,Ptr>  KKK;
		Node* _node;//指向节点的指针
		//构造函数
		__list_node(Node*node)
			:_node(node)
		{}
		Ref& operator*()//这里是const迭代器的关键,返回的*it,就是指向的位置
		{
			return _node->_val;
		}
		KKK operator++()
		{
			_node = _node->_next;
			return *this;
		}
		KKK operator--()
		{
			_node = _node->_prev;
			return *this;
		}	
		KKK operator--(int)
		{
			Node tmp(*this);
			_node = _node->_prev;
			return tmp;
		}
		KKK operator++(int)
		{
			KKK tmp(*this);
			_node = _node->_next;
			return tmp;
		}
		bool operator!=(const KKK&it)//里面必须加const,因为返回的end()具有常性
		{
			return _node != it._node;
		}
		Ptr* operator->()//这里的T*也分为const和不带const,所以加上class Ptr
		{
			return &_node->_val;
		}
	};
	//list,带头双向链表
	template<class T>
	class list
	{
		typedef list_node<T> Node;//相当于私有
	public:
		//迭代器
		typedef __list_node<T,T&, T*>  iterator;//第三个T*是为了operator->的重载
		//const迭代器
		//typedef const __list_node<T>  const_iterator;这种写法是错误的,因为const后的对象无法
		                                                                             //修改,但我们需要的是it++,可以被修改,不被修改的是
															//指向的内容不被修改
															
		//正确写法
		typedef __list_node<T,const T&,const T*>  const_iterator;
		//构造函数
		list()
		{
			_head = new Node;// new一个类型就相当于new一个这个类型的空间
			_head->_next = _head;
			_head->_prev = _head;
		}
		//尾插
		void push_back(const T&x)
		{
			//Node* newnode = new Node(x);//初始化为x,()是初始化[]开空间
			先把尾结点和头结点连接起来
			//Node* tail = _head->_prev;//一开始时,_head_>prev指向的是自己
			//tail->_next = newnode;//一开始要把_head的prev和next与newnode连接起来
			//newnode->_prev = tail;
			//newnode->_next = _head;
			//_head->_prev = newnode;
			insert(end(),x);
		}
		iterator begin()
		{
			return _head->_next;
		}
		iterator end()
		{
			return _head;//左闭右开
		}
		const_iterator begin() const
		{
			return _head->_next;
		}
		const_iterator end() const
		{
			return _head;//左闭右开
		}
		//pos位置前插入
		iterator insert(iterator pos,const T&x)
		{
			Node* newnode = new Node(x);
			Node* cur = pos._node;//先存一下pos位置的指针
			Node* prev = cur->_prev;//再存一下没插入之前pos前面节点的指针
			cur->_prev = newnode;
			newnode->_next = cur;
			newnode->_prev = prev;
			prev->_next = newnode;
			
			return newnode;
		}
		//pos位置的删除
		iterator erase(iterator pos)
		{
			assert(pos != end());//不能删除头结点
			Node* cur = pos._node;//存一下pos的节点指针
			Node* prev = cur->_prev;//存一下pos之前节点的指针
			Node* next = cur->_next;//存一下pos下一个节点的指针
			//连接pos位置前一个和后一个的节点,然后释放pos的空间
			prev->_next = next;
			next->_prev = prev;
			
			delete[]  cur;//加不加[]都行
			return next;
		}
		void pop_back() 
		{ 
			erase(--end()); 
		}
		void push_front(const T& val) 
		{ 
			insert(begin(), val); 
		}
		void pop_front() 
		{ 
			erase(begin()); 
		}
		size_t size()
		{
			size_t i = 0;
			auto it = begin();
			while (it != end())
			{
				i++;
				it++;
			}
			return i;
		}
		//clear,顺序表vector不需要释放空间,因为没法单独释放一部分空间,而链表list可以
		void clear()
		{
			auto it = begin();
			while (it != end())
			{
				it = erase(it);//这里会释放空间
				it++;
			}
			_size = 0;
		}
		//析构
		~list()
		{
			clear();
			delete _head;
			_head = nullptr;
		}
		//拷贝构造//必须要有一个头结点
		list(const list<T>& It)
		{
			//必须要有一个头结点
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
			auto it = It.begin();
			while (it != It.end())
			{
				push_back(*it);
				it++;
			}
		}
		void swap(list<T>&It)
		{
			std::swap(_head, It._head);
			std::swap(_size, It._size);
		}
		//=的实现
		list<T>& operator=(list<T>&It)
		{
			//现代写法用swap
			swap(It);
			return *this;
		}
	private:
		Node*_head;
		size_t _size;
	};
	void test1()
	{
		list<int>v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		list<int>::iterator it = v.begin();//这里是浅拷贝,不是赋值,迭代器不用写析构
		while (it != v.end())
		{
			cout << *it << " ";
			it++;
		}
	}
	void test2()
	{
		list<int>v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(3);
		v.insert(v.begin(), 9);
		
		auto it = v.begin();
		while(it!=v.end())
		{
			if (*it % 3 == 0)
			{
				it = v.erase(it);
			}
			else
			{
				it++;
			}	
		}
		for (auto e : v)
		{
			cout << e << " ";
		}
		cout << endl;
		cout<<v.size();
	}
	void test3()
	{
		list<int>v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(3);
		list<int>v1(v);
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
		list<int>v2;
		v2.push_back(10);
		v2.push_back(20);
		v2.push_back(30);
		v1 = v2;
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
	}
}