list模拟实现

全文目录

  • 代码
  • 注意事项
    • 迭代器
    • 迭代器的`operator->`

代码

#pragma once

#include <iostream>
#include <assert.h>

using namespace std;

namespace zwj
{
	template<typename T>
	struct list_node
	{
		T _data;
		list_node* _next;
		list_node* _prev;

		list_node(const T& x = T())
			: _data(x)
			, _next(this)
			, _prev(this)
		{}
	};


	// 多个模板参数,Ref表示引用,Ptr表示指针
	template<typename T, typename Ref, typename Ptr>
	class __list_iterator
	{
	public:
		typedef list_node<T> Node;
		//typedef __list_iterator             iterator;
		//typedef __list_iterator const_iterator;
		typedef __list_iterator<T, Ref, Ptr>           self;

		
		__list_iterator(Node* x)
			: _node(x)
		{}

		bool operator==(const self& x)
		{
			return _node == x._node;
		}

		bool operator!=(const self& x)
		{
			return _node != x._node;
		}
		
		Ref operator*()
		{
			return _node->_data;
		}

		Ptr operator->()
		{
			return &(operator*());
		}

		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		self operator++(int)
		{
			self tmp(*this);
			++(*this);
			return tmp;
		}

		self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}

		self operator--(int)
		{
			self tmp(*this);
			--(*this);
			return tmp;
		}

		Node* _node;
	};


	template<typename T>
	class list
	{
	public:
		typedef list_node<T> Node;

		// 迭代器
		typedef __list_iterator<T, T&, T*>             iterator;
		typedef __list_iterator<T, const T&, const T*> const_iterator;

		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())
		{}

		// fill构造
		list(size_t n, const T& val = T())
			: _head(new Node())
		{
			Node* tail = _head->_prev;

			for (size_t i = 0; i < n; i++)
			{
				Node* newNode = new Node(val);

				tail->_next = newNode;
				newNode->_prev = tail;
				newNode->_next = _head;
				_head->_prev = newNode;

				tail = tail->_next;
			}
		}

		// 迭代器区间构造
		list(iterator first, iterator last)
			: _head(new Node(T()))
		{
			Node* tail = _head->_prev;
			while (first != last)
			{
				Node* newNode = new Node(*first);
				
				tail->_next = newNode;
				newNode->_prev = tail;
				newNode->_next = _head;
				_head->_prev = newNode;

				tail = tail->_next;
			}
		}

		// copy构造
		list(const list& x)
			: _head(new Node(T()))
		{
			for (auto& e : x)
			{
				push_back(e);
			}
		}

		// 析构
		~list()
		{
			Node* tail = _head->_next;
			while (tail != _head)
			{
				Node* del = tail;
				tail = tail->_next;

				delete del;
			}

			delete _head;
			_head = nullptr;
		}

		// 尾插
		void push_back(const T& val)
		{
			Node* tail = _head->_prev;
			Node* newNode = new Node(val);
			
			tail->_next = newNode;
			newNode->_prev = tail;
			newNode->_next = _head;
			_head->_prev = newNode;
		}

		// 尾删
		void pop_back()
		{
			assert(_head != _head->_prev);
			
			Node* del = _head->_prev;
			Node* tail = del->_prev;
			_head->_prev = tail;
			tail->_next = _head;

			delete del;
		}

		// 头插
		void push_front(const T& val)
		{
			Node* head = _head->_next;
			Node* newNode = new Node(val);
			newNode->_next = head;
			head->_prev = newNode;
			newNode->_prev = _head;
		}

		// 头删
		void pop_front()
		{
			Node* del = _head->_next;
			_head->_next = del->_next;
			del->_prev = _head;

			delete del;
		}

		void insert(iterator pos, const T& val)
		{
			Node* tail = pos._node;
			Node* newNode = new Node(val);

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

		
		void erase(iterator pos)
		{
			Node* del = pos._node;
			Node* prev = del->_prev;
			Node* next = del->_next;
			prev->_next = next;
			next->_prev = prev;

			delete del;
		}

	private:
		Node* _head;
	};

	// 重载的输出函数
	template<typename T>
	ostream& operator<<(ostream& out, const list<T>& lt)
	{
		for (const auto& e : lt)
			out << e << ' ';

		out << endl;

		return out;
	}
};

注意事项

迭代器

list的迭代器因为其结构在内存中不是连续存储的,所以不能使用原生指针,需要使用模板类来进行封装一层,通过运算符重载来保证迭代器的正确迭代。

迭代器的operator->

Ptr operator->()
{
	return &(operator*());
}

当存放的对象是自定义类型的地址时,返回的是对象的地址,编译器在编译的时候会帮自动加上一个->it->_a 相当于:it->->_a

你可能感兴趣的:(C++,#,数据结构,list,c++,算法)