list的模拟实现

目录

1.list的节点

2.list迭代器的实现

3.list的具体实现

[3.1 insert](#3.1 insert)

[3.2 erase](#3.2 erase)

[3.3 push_back 和push_front](#3.3 push_back 和push_front)

[3.4pop_back 和 pop_front](#3.4pop_back 和 pop_front)

3.5构造函数

[3.6 operator=](#3.6 operator=)

[3.7 析构函数的实现](#3.7 析构函数的实现)

4.完整代码实现


1.list的节点

c**++中list的用的是带头双向循环链表,list本身和list节点并不是同一个内容需要分开设计.**

以下是list节点的结构

cpp 复制代码
	template<class T>
	struct __list_node {
	    __list_node(const T& val)
		    :_val(val)
		    , _next(nullptr)
		    , _prve(nullptr)
		    {}
		T _val;
		list_node<T>* _next;
		list_node<T>* _prve;
	};

这很明显是一个双向的结构

2.list迭代器的实现

我们先来回顾一下vector的迭代器是如何实现的?vector的空间是连续的迭代器可以是原生指针对于begin和end来说直接返回_start,_finish就可以了.

cpp 复制代码
vector的迭代器的实现
T是模版参数
typedef T* iterator;
typedef const T* const_iterator

iterator begin () {
    return _start;
}

iterator end() {
    return _finish;
}

对于我们的list来说空间不是连续的不能直接想vector一样返回原生指针.这个时候我们的迭代器要如何实现呢? 我们需要list的节点封装成一个类,利用运算符重载就可以像指针一样使用,然后就可以实现迭代器.

list迭代器的实现

cpp 复制代码
	template<class T,class Ref,class Ptr>
	struct list_iterator {
		typedef __list_node<T> Node;
		typedef list_iterator<T, Ref, Ptr> Self;

		Node* _node;
		list_iterator(Node* node) 
			:_node(node)
		{}

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

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

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

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

		Self& operator--() {
			_node = _node->_prve;
			return *this;
		}

		Self operator--(int) {
			Self tmp(*this);
			_node = _node->_prve;
			return tmp;
		}

		bool operator==(const Self& it) const {
			return _node == it._node;
		}

		bool operator!=(const Self& it) const {
			return _node != it._node;
		}
	};

大家可能这里会不明白,这里为什么要多加两个模版参数Ref和Ptr呢?如果不加这两个模版参数行不行呢?如果不加这两个参数也可实现list的迭代器,但是在我们解引用之后返回.只能返回 T& 或者是 const T& ,只能实现一种迭代器如果实现普通迭代器就不能实现const迭代器.如果要实现需要重新拷贝一份代码把返回值改成const T&或者是 T&,但是这样会造成代码重复.

不加Ref或Ptr两个模版参数实现的版本

普通迭代器

cpp 复制代码
    普通迭代器
	template<class T>
	struct list_iterator {
		typedef __list_node<T> Node;
		typedef list_iterator<T> Self;

		Node* _node;
		list_iterator(Node* node) 
			:_node(node)
		{}

		T& operator*() {
			return _node->_val;
		}

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

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

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

		Self& operator--() {
			_node = _node->_prve;
			return *this;
		}

		Self operator--(int) {
			Self tmp(*this);
			_node = _node->_prve;
			return tmp;
		}

		bool operator==(const Self& it) const {
			return _node == it._node;
		}

		bool operator!=(const Self& it) const {
			return _node != it._node;
		}
	};

const 迭代器

cpp 复制代码
   普通迭代器
	template<class T>
	struct list_iterator {
		typedef __list_node<T> Node;
		typedef list_iterator<T> Self;

		Node* _node;
		list_iterator(Node* node) 
			:_node(node)
		{}

		const T& operator*() {
			return _node->_val;
		}

		const T* operator->() {
			return &(operator*());
		}

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

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

		Self& operator--() {
			_node = _node->_prve;
			return *this;
		}

		Self operator--(int) {
			Self tmp(*this);
			_node = _node->_prve;
			return tmp;
		}

		bool operator==(const Self& it) const {
			return _node == it._node;
		}

		bool operator!=(const Self& it) const {
			return _node != it._node;
		}
	};

如果我们加上这两个模版参数我们可以用一份代码实现两个位置的迭代器,指定参数就可以了.

cpp 复制代码
typedef list_iterator<T,T&,T*> iterator;
typedef list_iterator<T,const T&,const T*> const_iterator;

3.list的具体实现

准备工作

cpp 复制代码
template<class T>
class list {
	typedef __list_node<T> Node;

public:
		typedef list_iterator<T, T&, T*> iterator;
		typedef list_iterator<T, const T&, const T*> const_iterator;

		iterator begin() {
			return _head->_next;
		}

		iterator end() {
			return _head;
		}

		const_iterator begin() const {
			return _head->_next;
		}
		const_iterator end() const{
			return _head;
		}     
private:
    Node* _head;
    size_t size;//用来记录节点的个数
}

3.1 insert

cpp 复制代码
iterator insert(iterator pos, const T& val) {
	Node* newnode = new Node(val);
	Node* node = pos._node;
	Node* prve = node->_prve;

	newnode->_prve = prve;
	prve->_next = newnode;

	node->_prve = newnode;
	newnode->_next = node;
	_size++;
	return newnode;
}

3.2 erase

cpp 复制代码
iterator erase(iterator pos) {
	assert(pos != end());

	Node* node = pos._node;
	Node* next = node->_next;
	Node* prve = node->_prve;

	prve->_next = next;
	next->_prve = prve;

	delete node;

	_size--;
	return next;
}

3.3 push_back 和push_front

cpp 复制代码
void push_back(const T& val) {
	insert(end(), val);
}

void push_front(const T& val) {
	insert(++end(), val);
}

3.4pop_back 和 pop_front

cpp 复制代码
void pop_back() {
	erase(--end());
}

void pop_front() {
	erase(++end());
}

3.5构造函数

cpp 复制代码
void init_empty() {
	_size = 0;
	_head = new Node;
	_head->_next = _head;
	_head->_prve = _head;
}

list() {
	init_empty();
}

list(initializer_list<T> lt) {
	init_empty();
	for (const auto& e : lt) {
		push_back(e);
	}
}

list(const list<T>& lt) {
	init_empty();
	for (const auto& e : lt) {
		push_back(e);
}

3.6 operator=

cpp 复制代码
void swap(list<T>& lt) {
	std::swap(_head,lt._head);
	std::swap(_size, lt._size);
}

list<T>& operator=(list<T> lt) {
	swap(lt);
	return *this;
}

3.7 析构函数的实现

cpp 复制代码
~list() {
	iterator it = begin();
	while (it != end()) {
		it = erase(it);
	}
	delete _head;
	_head = nullptr;
}

4.完整代码实现

cpp 复制代码
	template<class T>
	struct __list_node {
		
		__list_node(const T val = T()) 
			:_val(val)
			,_next(nullptr)
			,_prve(nullptr)
		{}


		T _val;
		__list_node<T>* _next;
		__list_node<T>* _prve;
	};

	template<class T,class Ref,class Ptr>
	struct list_iterator {
		typedef __list_node<T> Node;
		typedef list_iterator<T, Ref, Ptr> Self;

		Node* _node;
		list_iterator(Node* node) 
			:_node(node)
		{}

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

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

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

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

		Self& operator--() {
			_node = _node->_prve;
			return *this;
		}

		Self operator--(int) {
			Self tmp(*this);
			_node = _node->_prve;
			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 __list_node<T> Node;

		void init_empty() {
			_size = 0;
			_head = new Node;
			_head->_next = _head;
			_head->_prve = _head;
		}

	public:
		typedef list_iterator<T, T&, T*> iterator;
		typedef list_iterator<T, const T&, const T*> const_iterator;

		list() {
			init_empty();
		}

		list(initializer_list<T> lt) {
			init_empty();
			for (const auto& e : lt) {
				push_back(e);
			}
		}

		list(const list<T>& lt) {
			init_empty();
			for (const auto& e : lt) {
				push_back(e);
			}
		}

		~list() {
			iterator it = begin();
			while (it != end()) {
				it = erase(it);
			}
			delete _head;
			_head = nullptr;
		}

		void swap(list<T>& lt) {
			std::swap(_head,lt._head);
			std::swap(_size, lt._size);
		}

		list<T>& operator=(list<T> lt) {
			swap(lt);
			return *this;
		}

		iterator begin() {
			return _head->_next;
		}

		iterator end() {
			return _head;
		}

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

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


		void push_front(const T& val) {
			insert(++end(), val);
		}

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

		void pop_front() {
			erase(++end());
		}

		iterator insert(iterator pos, const T& val) {
			Node* newnode = new Node(val);
			Node* node = pos._node;
			Node* prve = node->_prve;

			newnode->_prve = prve;
			prve->_next = newnode;

			node->_prve = newnode;
			newnode->_next = node;
			_size++;
			return newnode;
		}

		iterator erase(iterator pos) {
			assert(pos != end());

			Node* node = pos._node;
			Node* next = node->_next;
			Node* prve = node->_prve;

			prve->_next = next;
			next->_prve = prve;

			delete node;

			_size--;
			return next;
		}

	private:
		Node* _head;
		size_t _size;
	};
相关推荐
晨非辰2 小时前
数据结构排序系列指南:从O(n²)到O(n),计数排序如何实现线性时间复杂度
运维·数据结构·c++·人工智能·后端·深度学习·排序算法
星期天26 小时前
3.0 C语⾔内存函数:memcpy memmove memset memcmp 数据在内存中的存储:整数在内存中的存储 ⼤⼩端字节序和字节序判断
c语言·数据结构·进阶·内存函数·数据内存存储
fashion 道格10 小时前
用 C 语言玩转归并排序:递归实现的深度解析
数据结构·算法·排序算法
j_xxx404_10 小时前
C++:继承(概念及定义|作用域|基类与派生类转换|默认成员函数|与友元、静态成员关系|多继承|组合)
数据结构·c++
码银11 小时前
【数据结构】 栈和队列
数据结构
Freedom_my12 小时前
插入排序算法
数据结构·算法·排序算法
9523612 小时前
排序-算法
数据结构·算法·排序算法
WongKyunban12 小时前
插入排序的原理和示例
数据结构·算法·排序算法
聪明绝顶的小Yya12 小时前
数据结构万字解读
数据结构
迈巴赫车主14 小时前
蓝桥杯 20541魔法科考试
java·数据结构·算法·蓝桥杯