Simular la implementación de la clase de lista

1. introducción de la lista

listes C++ STLun contenedor en , que es una lista doblemente enlazada que puede almacenar cualquier tipo de elemento. listLos elementos en se pueden insertar y eliminar de manera eficiente en la lista enlazada a través de punteros, por lo que listgeneralmente se usa en ocasiones que requieren operaciones frecuentes de inserción y eliminación.

2. Preparativos para implementar la clase de lista

1. Defina el nodo de la lista

Para distinguirlo de las clases de la biblioteca , podemos definir clases listen nuestro propio espacio de nombres . Solo hay una variable de miembro básica: el nodo principal ( ) y no se almacenan datos válidos en el nodo principal.listlistlisthead

Defina la estructura del nodo:

namespace dianxia
{
    
    
	//定义结点结构
	template<class T>
	struct ListNode
	{
    
    
		struct ListNode<T>* _next; // 指向下一个结点
		struct ListNode<T>* _prev; // 指向前一个结点
		T _data; // 结点存储的数据

		ListNode(const T& data = T()) // 构造函数 // 申请一个节点 
			:_next(nullptr),
			_prev(nullptr),
			_data(data)
		{
    
    }
	};
}

2. Definir el iterador de lista

Iterador: como listla parte más esencial, tiene un papel extremadamente importante y también es listla parte más difícil de la implementación de la simulación. ¡A través del contenido de este capítulo, nuestra comprensión de los iteradores mejorará!

En el estudio de stringy vector, a menudo usamos subíndices +[]para acceder a los elementos del contenedor, lo cual es muy conveniente. Pero en listel futuro, []el método de acceso a los elementos ya no será aplicable y usaremos iteradores.

El iterador se mencionó brevemente en el artículo anterior. En pocas palabras, es un puntero genérico pero no solo un puntero. A continuación, simularemos el listiterador implementado.

La esencia de un iterador es encapsular punteros para simular el comportamiento de los punteros , ++por lo que necesitamos simular la implementación de punteros --y otras operaciones a través de la sobrecarga de operadores .*->

Encapsulamos una serie de operaciones que los iteradores pueden implementar en clases:

	// 三个参数的含义分别为:
	//类型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* node)
			:_node(node)
		{
    
    }

		self& operator++()
		{
    
    
			_node = _node->_next;
			return *this;
		}
	
		self operator++(int)
		{
    
    
			self tmp(*this);
			_node = _node->_next;
			return tmp;
		}
	
		self& operator--()
		{
    
    
			_node = _node->_prev;
			return *this;
		}
	
		self operator--(int)
		{
    
    
			self tmp(*this);
			_node = _node->_prev;
			return tmp;
		}
	
		Ref& operator*()
		{
    
    
			return _node->_data;
		}
	
		Ptr& operator->()
		{
    
    
			return &(_node->_data);
		}
	
		bool operator==(const self& s)
		{
    
    
			return _node == s._node;
		}
	
		bool operator!=(const self& s)
		{
    
    
			return _node != s._node;
		}
	}

3. Simular la implementación de la clase de lista

Con listlos nodos y listlos iteradores, implementemos listlas funciones miembro de la propia clase:

1. Definir la clase de lista

	template<class T>
	class list
	{
    
    
		typedef ListNode<T> Node;
	public:
		// 类型重命名——普通迭代器
		typedef _list_iterator<T,T&,T*> iterator; 
		// 类型重命名——const迭代器
		typedef _list_iterator<T, const T&,const T*> const_iterator; 
	
	private:
		Node _node; 
	}

2. Constructor y Destructor

	//构造函数
	list()
	{
    
    
		_head = new Node;
		_head->_next = _head;
		_head->_prev = _head;
	}
	//析构函数
	~list()
	{
    
    
		clean();
		delete _head;
		_head = nullptr;
	}

3. Funciones relacionadas con el iterador

	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);
	}

4. Insertar y eliminar operaciones relacionadas

	//插入操作
	void insert(iterator pos,const T& data)
	{
    
    
		node* newNode = new Node(data);

		Node* cur = pos._node;
		Node* prev = cur->_prev;

		newNode->_prev = prev;
		prev->_next = newNode;
		newNode->_next = cur;
		cur->_prev=newNode;
	}
	//删除操作
	iterator erase(iterator pos)
	{
    
    
		assert(pos != end());
		Node* prev = pos._node->_prev;
		Node * next = pos._node->_next;

		prev->_next = next;
		next->_prev = prev;
		delete pos._node;
		
		// 返回删除位置的下一个迭代器位置
		return iterator(next); 
	}
	//尾插
	void push_back(const T& data)
	{
    
    
		insert(end(),data);
	}
	//尾删
	void pop_back()
	{
    
    
		erase(--end());
	}
	//头插
	void push_front(const T& data)
	{
    
    
		insert(begin(), data);
	}
	//头删
	void pop_front()
	{
    
    
		erase(begin());
	}
	//清空list
	void clean() 
	{
    
    
		iterator it = begin();
		while (it != end())
		{
    
    
			//it = erase(it);
			erase(it++);
		}
	}

5. Copiar construcción

	void swap(list<T>& tmp)
	{
    
    
		std::swap(_head, tmp._head);
	}
	//拷贝构造
	list(const list<T>& lt)
	{
    
    
		//初始化
		_head = new node;
		_head->_next = _head;
		_head->_prev = _head;

		//复用区间构造
		list<T> tmp(lt.begin(), lt.end());
		swap(tmp);
	}

6. Sobrecarga de tareas

	void swap(list<T>& tmp)
	{
    
    
		std::swap(_head, tmp._head);
	}
	//赋值重载
	list<T>& operator=(list<T> lt)
	{
    
    
		swap(lt);
		return *this;
	}

4. Código fuente

#include<iostream>
#include<assert.h>
using namespace std;
namespace dianxia
{
    
    
	//定义list节点
	template<class T>
	struct ListNode
	{
    
    
		struct ListNode<T>* _next; // 指向下一个结点
		struct 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* node)
			:_node(node)
		{
    
    }

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

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

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

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

		Ref& operator*()
		{
    
    
			return _node->_data;
		}

		Ptr& operator->()
		{
    
    
			return &(_node->_data);
		}

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

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


	// list类的定义
	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;

		list()
		{
    
    
			_head = new node;
			_head->_next = _head;
			_head->_prev = _head;
		}

		// 迭代器区间构造
		template<class Iterator>
		list(Iterator begin, Iterator end)
		{
    
    
			//初始化
			_head = new node;
			_head->_next = _head;
			_head->_prev = _head;

			while (begin != end)
			{
    
    
				push_back(*begin);
				++begin;
			}
		}
		void swap(list<T>& tmp)
		{
    
    
			std::swap(_head, tmp._head);
		}
		//拷贝构造
		list(const list<T>& lt)
		{
    
    
			//初始化
			_head = new node;
			_head->_next = _head;
			_head->_prev = _head;

			//复用区间构造
			list<T> tmp(lt.begin(), lt.end());
			swap(tmp);
		}

		//赋值重载
		list<T>& operator=(list<T> lt)
		{
    
    
			swap(lt);
			return *this;
		}

		~list()
		{
    
    
			clean();
			delete _head;
			_head = nullptr;
		}

		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);
		}

		void push_back(const T& data)
		{
    
    
			insert(end(),data);
		}

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

		void push_front(const T& data)
		{
    
    
			insert(begin(), data);
		}

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

		void insert(iterator pos, const T& data)
		{
    
    
			node* newNode = new node(data);

			node* cur = pos._node;
			node* prev = cur->_prev;

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

		iterator erase(iterator pos)
		{
    
    
			assert(pos != end());
			node* prev = pos._node->_prev;
			node* next = pos._node->_next;

			prev->_next = next;
			next->_prev = prev;
			delete pos._node;

			return iterator(next); // 返回删除位置的下一个迭代器位置
		}

		void clean()
		{
    
    
			iterator it = begin();
			while (it != end())
			{
    
    
				//it = erase(it);
				erase(it++);
			}
		}
	private:
		node* _head;
	};
}


Este es el final de este artículo, el texto del código no es fácil, ¡por favor ayúdenme mucho! !

Supongo que te gusta

Origin blog.csdn.net/weixin_67401157/article/details/131833023
Recomendado
Clasificación