list模拟实现--代码详解

list模拟实现

由于list的底层是双向链表结构,因此在进行list模式实现时需要先定义一个结构体(节点),成员定义为三个:
_data:用来保存数据
_prev:用来指向上一个节点的指针
_next:用来指向下一个节点的指针

template <class T>
struct ListNode
{
	T _data;
	ListNode<T>* _next;
	ListNode<T>* _prev;

	ListNode(const T& val = T())
		:_data(val)
		, _next(nullptr)
		, _prev(nullptr)
	{}
};

之前实现vector迭代器时定义的begin函数直接返回start指针(该指针直接指向数据本身)。但由于在实现list迭代器时,list的指针指向的是节点类型。节点由包括data、prev、next。因此在进行解引用时,不会得到数据本身,同时进行++操作时也不会得到下一个节点的位置。
因此还需要定义一个迭代器结构体,其成员定义为:
_node:指向节点类型的指针。
同时也要重载一些运算符函数星号和++操作等,即实现以下逻辑(举例):
*it:_node->data;
++it:_node->next;

template <class T, class Ref, class Ptr>
struct ListIterator
{
	typedef ListIterator<T, Ref, Ptr> Self;

	ListIterator(ListNode<T>* node)
		:_node(node)
	{}

	//*iterator:获取数据本身
	Ref operator*()
	{
		return _node->_data;
	}

	//it->_a:内置类型可以通过解引用*来获得数据,当想引用自定义类型中的成员时,需要返回T*类型指针,再根据指针指向来获取自定义类型成员
	//如:A* ptr = new A(1,2,3)  自定义类型A中有三个成员_a,_b,_c分别赋值1,2,3. 获取时cout << ptr->a << ptr->b << ptr->c << endl;  
	//那么在使用List迭代器进行获取的时候就需要重载->
	//因此在获得迭代器后 List<A>::iterator it = lst.begin(); 
	//全写:cout << it.operator->()->_a << it.operator->()->_b << it.operator->()->_c << endl;
	//简写:cout << it->_a << it->_b << it->_c << endl;
	Ptr operator->()
	{
		return &_node->_data;
	}


	//++iterator:
	Self& operator++()
	{
		_node = _node->_next;
		return *this;
	}

	//后置++:
	Self operator++(int)
	{
		ListIterator<T> tmp(*this);
		_node = _node->_next;
		return tmp;
	}

	bool ooerator != (const Self& it)
	{
		//判断成员指针_node是否指向同一个节点
		return _node != it._node;
	}

	//it->_a:当定义一个自定义类型时
	T* operator->()
	{
		return &_node->_data;
	}

	bool operator==(const Self& it)
	{
		return !(*this != it);
	}

	//封装节点
	ListNode<T>* _node;
}; 

之后再开始实现list类,成员定义为一个:
_header:指向先前定义的节点结构体类型的指针
该list中析构函数的实现与先前stirng和vector不同在于需要循环释放每个节点的资源。

template <class T>
class List
{
public:
	typedef ListNode<T> Node;
	typedef Node* pNode;
	typedef ListIterator<T, T&, T*> iterator;
	typedef ListIterator<T, const T&, const T*> const_iterator;

	iterator begin()
	{
		return iterator(_header->_next);
	}
	const_iterator begin() const
	{
		return const_iterator(_header->_next);
	}
	iterator end()
	{
		return iterator(_header);
	}
	const_iterator end() const
	{
		return const_iterator(_header);
	}

	List()
		:_header(new Node())
	{
		//循环结构
		_header->_next = _header->_prev = _header;
	}
	List(size_t n, const T& val = T())
		:_header(new Node())
	{
		_header->_next = _header->_prev = _header;
		for (size_t i = 0; i < n; ++i)
		{
			pushBack(val);
		}
	}
	template <class inputIterator>
	List(inputIterator first, inputIterator last)
		:_header(new Node())
	{
		_header->_next = _header->_prev = _header;
		while (first != last)
		{
			pushBack(*first);
			++first;
		}
	}
	void pushBack(const T& val)
	{
		pNode prev = _header->_prev;
		Node newNode = List(val);

		prev->_next = newNode;
		newNode->_prev = prev;

		newNode->_next = _header;
		_header->_prev = newNode;
	}

	void insert(iterator pos, const T& val)
	{
		pNode cur = pos._node;
		pNode prev = cur->_prev;
		pNode newNode = new Node(val);

		prev->_next = newNode;
		newNode->_prev = prev;

		newNode->_next = cur;
		cur->_prev = newNode;
	}

	iterator erase(iterator pos)
	{
		//判断是否为end迭代器
		if (pos != end())
		{
			pNode cur = pos._node;
			pNode prev = cur->_prev;
			pNode next = cur->_next;

			delete cur;

			prev->_next = next;
			next->_prev = prev;

			//pos迭代器失效
			//更新迭代器:指向下一个元素
			return iterator(next);
		}
		return pos;
	}

	void popFront()
	{
		erase(begin());
	}

	void popBack()
	{
		erase(--end());
	}

	//传统写法:
	//List<T>& operator=(List<T>& lst)
	//{
	//	if (this != &lst)
	//	{
	//		//释放原有的节点
	//		Node* cur = _header->_next;
	//		while (cur != _header)
	//		{
	//			Node* next = cur->_next;
	//			delete cur;
	//			cur = next;
	//		}
	//		_header->_next = _header->_prev = _header;
	//		//拷贝
	//		for (auto& e : lst)
	//			pushBack(e);
	//	}
	//	return *this;
	//}

	//现代写法:
	List<T>& operator=(List<T> lst)
	{
		swap(_header, lst._header);
		return *this;
	}

	//深拷贝
	List(const List<T>& lst)
		:_header(new Node())
	{
		//循环结构
		_header->_next = _header->_prev = _header;

		//元素拷贝
		//Node* cur = lst._header->_next;
		//while (cur != lst._header)
		//{
		//	pushBack(cur->_data);
		//}
		//写法2:
		for (auto& e : lst)
			pushBack(e);
	}
	~List()
	{
		if (_header)
		{
			Node* node = _header->_next;
			while (node != _header)
			{
				Node* next = node->_next;
				delete node;
				node = next;
			}
			delete _header;
			_header = nullptr;
		}
	}

private:
	ListNode<T>* _header;
};

void test()
{
	List<int> lst;
	lst.pushBack(1);
	lst.pushBack(2);
	List<int> lst2((size_t)10, 5);

	string str = "12345";
	List<char> lst3(str.begin(), str.end());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值