C++ list 的模拟实现


list 实现接口总览

template <class T>
class list {
public:
	typedef ListNode<T> Node;
	typedef Iterator<T, T&, T*> iterator;
	typedef Iterator<T, const T&, const T*> const_iterator;
	typedef Reverse_Iterator<iterator, T&, T*> reverse_iterator;
	typedef Reverse_Iterator<const_iterator, const T&, const T*> const_reverse_iterator;

	//默认函数
	list();
	list(size_t n, const T& val = T());
	template <class InputIterator>
	list(InputIterator first, InputIterator last);
	list(const list<T>& lst);
	list<T>& operator=(const list<T>& lst);
	~list();

	//插入和删除
	void push_back(const T& val);
	void pop_back();
	void push_front(const T& val);
	void pop_front();
	iterator insert(iterator pos, const T& val);
	void insert(iterator pos, size_t n, const T& val);
	template <class InputIterator>
	void insert(iterator pos, InputIterator first, InputIterator last);
	iterator erase(iterator pos);
	iterator erase(iterator first, iterator last);

	//迭代器相关函数
	iterator begin();
	iterator end();
	const_iterator begin()const;
	const_iterator end()const;
	const_iterator cbegin()const;
	const_iterator cend()const;
	reverse_iterator rbegin();
	reverse_iterator rend();
	const_reverse_iterator rbegin()const;
	const_reverse_iterator rend()const;
	const_reverse_iterator crbegin()const;
	const_reverse_iterator crend()const;

	//访问元素函数
	T& front();
	const T& front()const;
	T& back();
	const T& back()const;

	//容器大小控制
	size_t size()const;
	void reszie(size_t n, const T& val = T());
	bool empty()const;
	void clear();

	//容器操作函数
	template <class Compare = bool(const T&, const T&)>
	void sort(Compare comp = compare_sort);
	
	void splice(iterator pos, list<T>& lst);
	void splice(iterator pos, list<T>& lst, iterator it);
	void splice(iterator pos, list<T>& lst, iterator first, iterator last);
	
	void remove(const T& val);
	template <typename Compare = bool(const T&)>
	void remove_if(Compare comp);

	template <class Compare = bool(const T&, const T&)>
	void unique(Compare comp = compare_unique);

	template <class Compare = bool(const T&, const T&)>
	void merge(list& lst, Compare comp = compare_sort);

	void reverse();

	void assign(size_t n, const T& val);
	template <class InputIterator>
	void assign(InputIterator first, InputIterator last);

	void swap(list& lst);

	template<class... Arg>
	iterator emplace(iterator pos, Arg&&... args);

private:
	bool compare_sort(const T& val1, const T& val2) {
		return val1 <= val2;
	}
	bool compare_unique(const T& val1, const T& val2) {
		return val1 == val2;
	}
	Node* _node;		//头结点
};

⭕️注意:

  1. list 是一个带头结点的双向循环链表,其头结点不含有效元素

  2. 为了防止与 C++ 中已有的 list 冲突,我们将自己模拟实现的 list 放到自己的命名空间

  3. 所有成员函数均在类外实现


一、节点类的实现

🍀list 节点类只需要实现构造函数即可,其析构在 list 容器类实现

template <class T>
struct ListNode {
	//构造函数
	ListNode(const T& val = T()) 
		:_val(val)
		, _next(nullptr)
		, _prev(nullptr) {}
	
	//成员变量
	T _val;
	ListNode* _next;
	ListNode* _prev;
};

🍀这里也可以使用 class 定义节点类,但是需要实现获取其成员变量的方法,或者将其设置成 list 的友元类,从而实现其他非类内函数获取成员变量

template <class T>
class ListNode {
public:
	ListNode(const T& val = T()) 
		:_val(val)
		,_next(nullptr)
		,_prev(nullptr) 
	{}
	ListNode*& next() {
		return this->_next;
	}
	ListNode*& prev() {
		return this->_prev;
	}
	T& get_val() {
		return this->_val;
	}
private:
	T _val;
	ListNode* _next;
	ListNode* _prev;
};

二、迭代器的实现

🍀与前面 vector 和 string 不同,我们不能再将迭代器直接定义为如下:

template <class T>
class list {
	typedef ListNode Node;
	//方式 1
	typedef Node* iterator;
	//方式 2
	typedef T* iterator;

	//else...
};

⭕️注意:

  1. 上面两种方式都是错误的,对于 vector 或者 string,其迭代器就是容器元素类型指针的重命名,所以对迭代器进行 ++ 或 -- 操作就是对指针进行这些操作,这些操作可以使指针(也就是迭代器)指向容器下一个元素所在的位置

  2. 对于 list ,如果直接将节点 Node* 设置成迭代器,那么对其进行 ++ 或 -- 操作不能实现将迭代器(指针)指向下一个元素所在位置,因为 list 的节点是离散存储的,正确操作应该如下(伪代码):

typedef Node* iterator;

iterator = iterator->_next;		//实现 ++ 操作
iterator = iterator->_prev		//实现 -- 操作

🍀所以正确做法是,将正向迭代器封装成一个类,方向迭代器作为正向迭代器的适配器(类似于 vector 迭代器的第二种实现方法)。具体代码实现如下:

//正向迭代器
template <class T, class Ref, class Ptr>
struct Iterator {
	typedef ListNode<T> Node;
	typedef Iterator<T, Ref, Ptr> self;
	Iterator(Node* it) :_it(it) {}

	self& operator++() {
		_it = _it->_next;
		return*this;
	}
	self operator++(int) {
		Node* tmp = _it;
		_it = _it->_next;
		return self(tmp);
	}
	self& operator--() {
		_it = _it->_prev;
		return *this;
	}

	self operator--(int) {
		Node* tmp = _it;
		_it = _it->_prev;
		return self(tmp);
	}
	Ref operator*() {
		return _it->_val;
	}
	Ptr operator->() {
		return &_it-_val;
	}
	bool operator==(const self& it) {
		return it._it == _it;
	}
	bool operator!=(const self& it) {
		return it._it != _it;
	}
	Node* _it;
};
//反向迭代器
template <class Iterator, class Ref, class Ptr>
struct Reverse_Iterator {
	typedef Reverse_Iterator<Iterator, Ref, Ptr> self;
	Reverse_Iterator(Iterator it) :_it(it) {}

	self& operator++() {
		++_it;
		return *this;
	}
	self operator++(int) {
		self tmp(_it++);
		return tmp;
	}
	self& operator--() {
		--_it;
		return *this;
	}
	self operator--() {
		self tmp(_it--);
		return tmp;
	}
	Ref operator*() {
		return *_it;
	}
	Ptr operator->() {
		return _it;
	}
	bool operator==(const self& it) {
		return it._it == _it;
	}
	bool operator!=(const self& it) {
		return it._it != it;
	}
	
	Iterator _it;
};
//list 容器中
template <class T>
class list {
public:
	typedef ListNode<T> Node;
	typedef Iterator<T, T&, T*> iterator;
	typedef Iterator<T, const T&, const T*> const_iterator;
	typedef Reverse_Iterator<iterator, T&, T*> reverse_iterator;
	typedef Reverse_Iterator<const_iterator, const T&, const T*> const_reverse_iterator;
	//else...
private:
	Node* _node;
);

🍀说明:

  1. 上面的实现方法在 vector 中已经说过一次,这里不在赘述

  2. 这里设计的迭代器的拷贝构造都是浅拷贝,因为拷贝的是迭代器的成员变量(节点指针),并没有拷贝这个节点

  3. 迭代器不需要实现析构函数,因为其不需要释放节点,这是 list 容器需要考虑的问题

  4. 关于 operator->():我们返回的是节点的指针(Node*),因为事实上,一个类指针使用 -> 访问成员变量时,就会先调用其实现的 operator-> 返回这个类的指针,然后再通过整个指针访问数据,例如:

class Date {
	public:
		int day;
};
Date* d = new Date;
d->day;		//相当于 d->operator->()->day 或者 d->->day
//但是这样太别扭,所以编译器进行了优化,可以直接写成 d->day

🍀总结:迭代器的意义就是让使用者可以不用关系容器底层实现,可以用简单统一的方式对容器进行访问,但是如果 list 将迭代器定义成节点指针(Node*),那么就与其意义不符


三、list 的模拟实现

默认成员函数

构造函数
template <typename T>
list<T>::list() :_node(nullptr) {
	_node = new Node;	//申请头结点
	_node->_next = _node;
	_node->_prev = _node;
}

template <typename T>
template <typename InputIterator>
list<T>::list(InputIterator first, InputIterator last) {
	_node = new Node;
	Node* prev = _node;
	for (InputIterator it = first; it != last; it++) {
		Node* cur = new Node(*it);
		prev->_next = cur;
		cur->_prev = prev;
		prev = cur;
	}
	prev->_next = _node;
	_node->_prev = prev;
}

template <typename T>
list<T>::list(size_t n, const T& val) :_node(nullptr) {
	_node = new Node;
	_node->_next = _node;
	_node->_prev = _node;
	resize(n, val);
}

🍀注意:第三个构造函数应当还要实现两个重载(具体原因可以看 vector 的模拟实现):

list<T>::list(int n, const T& val);

list<T>::list(long n, const T& val);

拷贝构造函数
template <typename T>
list<T>::list(const list<T>& lst) {
	_node = new Node;
	_node->_next = _node;
	_node->_prev = _node;
	for (const auto& e : lst) {
		push_back(e);
	}
}

赋值运算符重载 operator=

下面提供两种写法:

//传统写法
template <typename T>
list<T>& list<T>::operator=(const list<T>& lst) {
	if (&lst != this) {
		clear();
		for (const auto& e : lst) {
			push_back(e);
		}
	}
	return *this;
}
//现代写法
template <typename T>
list<T>& list<T>::operator=(const list<T>& lst) {
	if (&lst != this) {
		list<T> tmp(lst);
		::swap(_node, tmp._node);
	}
	return *this;
}

析构函数
template <typename T>
list<T>::~list() {
	clear();
	delete _node;	//释放头结点
	_node = nullptr;
}

迭代器相关函数

template <typename T>
typename list<T>::iterator list<T>::begin() {
	return iterator(_node->_next);
}

template <typename T>
typename list<T>::iterator list<T>::end() {
	return iterator(_node);
}

template <typename T>
typename list<T>::const_iterator list<T>::begin()const {
	return const_iterator(_node->_next);
}

template <typename T>
typename list<T>::const_iterator list<T>::end()const {
	return const_iterator(_node);
}

template <typename T>
typename list<T>::const_iterator list<T>::cbegin()const {
	return const_iterator(_node->_next);
}

template <typename T>
typename list<T>::const_iterator list<T>::cend()const {
	return const_iterator(_node);
}

template <typename T>
typename list<T>::reverse_iterator list<T>::rbegin() {
	return reverse_iterator(iterator(_node->_prev));
}

template <typename T>
typename list<T>::reverse_iterator list<T>::rend() {
	return reverse_iterator(iterator(_node));
}

template <typename T>
typename list<T>::const_reverse_iterator list<T>::rbegin()const {
	return const_reverse_iterator(const_iterator(_node->_prev));
}

template <typename T>
typename list<T>::const_reverse_iterator list<T>::rend()const {
	return const_reverse_iterator(const_iterator(_node));
}

template <typename T>
typename list<T>::const_reverse_iterator list<T>::crbegin()const {
	return const_reverse_iterator(const_iterator(_node->_prev));
}

template <typename T>
typename list<T>::const_reverse_iterator list<T>::crend()const {
	return const_reverse_iterator(const_iterator(_node));
}

访问容器相关函数

front() 和 back()

⭕️注意:front() 和 back() 返回的均为引用

template <typename T>
T& list<T>::front() {
	assert(!empty());
	return _node->_next->_val;
}
template <typename T>
const T& list<T>::front()const {
	assert(!empty());
	return _node->_next->_val;
}

template <typename T>
T& list<T>::back() {
	assert(!empty());
	return _node->_next->_val;
}
template <typename T>
const T& list<T>::back()const {
	assert(!empty());
	return _node->_next->_val;
}

容器元素的插入和删除

insert()
template <typename T>
typename list<T>::iterator list<T>::insert(iterator pos, const T& val) {
	Node* new_node = new Node(val);
	Node* pos_node = pos._it;
	pos_node->_prev->_next = new_node;
	new_node->_prev = pos_node->_prev;
	pos_node->_prev = new_node;
	new_node->_next = pos_node;
	return iterator(new_node);
}

template <typename T>
void list<T>::insert(iterator pos, size_t n, const T& val) {
	for (size_t i = 0; i < n; i++) {
		pos = insert(pos, val);
	}
}

template <typename T>
template <typename InputIterator>
void list<T>::insert(iterator pos, InputIterator first, InputIterator last) {
	for (InputIterator it = first; it != last; it++) {
		insert(pos, *it);
	}
}

erase()
template <typename T>
typename list<T>::iterator list<T>::erase(iterator pos) {
	Node* pos_node = pos._it;
	pos_node->_prev->_next = pos_node->_next;
	pos_node->_next->_prev = pos_node->_prev;
	Node* ret = pos_node->_next;
	delete pos_node;
	pos_node = nullptr;
	return iterator(ret);
}

template <typename T>
typename list<T>::iterator list<T>::erase(iterator first, iterator last) {
	for (iterator it = first; it != last;) {
		it = erase(it);
	}
	return last;
}

push_back() 和 pop_back()
template <typename T>
void list<T>::push_back(const T& val) {
	Node* new_node = new Node(val);
	_node->_prev->next = new_node;
	new_node->_prev = _node->_prev;
	_node->_prev = new_node;
	new_node->_next = _node;
}

template <typename T>
void list<T>::pop_back() {
	if (!empty()) {
		Node* target = _node->_prev;
		_node->_prev = target->_prev;
		target->_prev->_next = _node;
		delete target;
		target = nullptr;
	}
}

push_front() 和 pop_front()
template <typename T>
void list<T>::push_front(const T& val) {
	Node* new_node = new Node(val);
	_node->_next->_prev = new_node;
	new_node->_next = _node->_next;
	new_node->_prev = _node;
	_node->_next = new_node;
}

template <typename T>
void list<T>::pop_front() {
	if (!empty()) {
		Node* target = _node->_next;
		_node->_next = target->_next;
		target->_next->_prev = _node;
		delete target;
		target = nullptr;
	}
}

容器大小相关函数

size() 和 resize()
template <typename T>
size_t list<T>::size()const {
	Node* first = _node->_next;
	size_t size = 0;
	while (first != _node) {
		++size;
		first = first->_next;
	}
	return size;
}

template <typename T>
void list<T>::resize(size_t n, const T& val) {
	if (size() <= n) {
		insert(end(), n - size(), val);
	}
	else {
		//未重载 iterator 的 - 操作,会报错
		erase(end() - size() + n, end());		
	}
}

empty() 和 clear()
template <typename T>
bool list<T>::empty()const {
	return _node->_next == _node;
}

//删除容器中所有有效元素(不删除头结点)
template <typename T>
void list<T>::clear() {
	erase(begin(), end());
}

容器操作函数

sort()
template <class T>
class list {
public:
	//函数模板参数设置缺省值
	template <class Compare = bool(const T&, const T&)>
	void sort(Compare comp = compare_sort);
	//else...
private:
	//默认升序排序的比较函数	
	bool compare_sort(const T& val1, const T& val2) {
		return val1 <= val2;
	}
	//else...
};

template <typename T>
template <typename Compare>
void list<T>::sort(Compare comp) {
	//使用选择排序这里只交换元素值,不交换整个节点
	for (iterator first = begin(); first != end(); first++) {
		for (iterator it = first; it != end(); it++) {
			if (!comp(first._it->_val, it._it->_val)) {
				::swap(first._it->_val, it._it->_val);
			}
		}
	}
}

🍀说明:

  1. 这里我们的排序只实现了交换节点里面的值,并没有交换整个节点

  2. 我们在 list 类中实现了一个进行升序排序的比较函数,并将其设置为 sort() 函数的缺省值,所以 sort() 函数可以默认实现升序排序


splice()
template <typename T>
void list<T>::splice(iterator pos, list<T>& lst, iterator first, iterator last) {
	//insert(pos, first, last);	 //error
	Node* first_prev = first->_it->_prev;
	Node* pos_node = pos->_it;
	for (iterator it = first; it != last; it++) {
		Node* it_node = it->_it;
		it_node->_prev = pos_node->_prev;
		pos_node->_prev->_next = it_node;
		it_node->_next = pos_node;
		pos_node->_prev = it_node;
	}
	//删除 lst 中已经拼接的元素
	first_prev->_next = last._it;
	last._it->_prev = first_prev;
}

template <typename T>
void list<T>::splice(iterator pos, list<T>& lst, iterator it) {
	splice(pos, lst, it, it + 1);
}

template <typename T>
void list<T>::splice(iterator pos, list<T>& lst) {
	splice(pos, lst.begin(), lst.end());
}

🍀说明:

  1. 我们不能使用 insert(pos, first, last),因为该函数的节点是在插入时临时 new 出来的,而 splice() 中的插入到容器中的节点是另外一个容器中已经存在的节点

  2. 当容器被拼接后,需要删除被拼接的元素节点,但并不是真的删除(delete),而是改变相应的节点 next 和 prev 指针指向


remove 和 remove_if
template <typename T>
void list<T>::remove(const T& val) {
	for (iterator it = begin(); it != end(); it++) {
		if (*it == val) {
			erase(it);
		}
	}
}

template <class T>
class list {
public:
	//else...
	template <class Compare = bool(const T&)>
	void remove_if(Compare comp);
private:
	//else...
};
template <typename T>
template <typename Compare>
void list<T>::remove_if(Compare comp) {
	for (iterator it = begin(); it != end(); it++) {
		if (comp(*it)) {
			erase(it);
		}
	}
}

unique()
template <class T>
class list {
public:
	template <class Compare = bool(const T&, const T&)>
	void unique(Compare comp = compare_unique);
private:
	bool compare_unique(const T& val1, const T& val2) {
		return val1 == val2;
	}
	//else...
}

template <typename T>
template <typename Compare>
void list<T>::unique(Compare comp) {
	for (iterator it = begin() + 1; it != end();) {
		iterator target = it++;
		if (comp(*it, *(it - 1))) {
			erase(target);
		}
	}
}

merge()
template <typename T>
template <typename Compare>
void list<T>::merge(list& lst, Compare comp) {
	iterator start = lst.begin();
	while (start != lst.end()) {
		iterator it = begin();
		while (it != end()) {
			if (comp(*start, *it)) {
				splice(it, lst, start);
				break;
			}
		}
		if (it == end()) {
			insert(end(), start, lst.end());
			break;
		}
		start++;
	}
}

reverse()
template <typename T>
void list<T>::reverse() {
	size_t size = size();
	Node* last = _node->_prev;
	Node* first = _node->_next;
	for (size_t i = 0; i < size; i++) {
		first->_prev = last;
		last->_next = first;
		first = last;
		last = last->_prev;
	}
	_node->_next = first;
	_node->_prev = last;
}

assign()
template <typename T>
void list<T>::assign(size_t n, const T& val) {
	clear();
	resize(n, val);
}

template <typename T>
template <typename InputIterator>
void list<T>::assign(InputIterator first, InputIterator last) {
	clear();
	insert(begin(), first, last);
}

swap()
template <typename T>
void list<T>::swap(list& lst) {
	::swap(_node, lst._node);
}

完整代码

list.h 文件

#pragma once
#include <cassert>
namespace yw {
	//节点类
	template <class T>
	struct ListNode {
		ListNode(const T& val = T()) :_val(val), _next(nullptr), _prev(nullptr) {}
		T _val;
		ListNode* _next;
		ListNode* _prev;
	};
	//正向迭代器
	template <class T, class Ref, class Ptr>
	struct Iterator {
		typedef ListNode<T> Node;
		typedef Iterator<T, Ref, Ptr> self;
		Iterator(Node* it) :_it(it) {}

		self& operator++() {
			_it = _it->_next;
			return*this;
		}
		self operator++(int) {
			Node* tmp = _it;
			_it = _it->_next;
			return self(tmp);
		}
		self& operator--() {
			_it = _it->_prev;
			return *this;
		}
		self operator--(int) {
			Node* tmp = _it;
			_it = _it->_prev;
			return self(tmp);
		}
		Ref operator*() {
			return _it->_val;
		}
		Ptr operator->() {
			return _it;
		}
		bool operator==(const self& it) {
			return it._it == _it;
		}
		bool operator!=(const self& it) {
			return it._it != _it;
		}
		Node* _it;
	};
	//反向迭代器
	template <class Iterator, class Ref, class Ptr>
	struct Reverse_Iterator {
		typedef Reverse_Iterator<Iterator, Ref, Ptr> self;
		Reverse_Iterator(Iterator it) :_it(it) {}

		self& operator++() {
			++_it;
			return *this;
		}
		self operator++(int) {
			self tmp(_it++);
			return tmp;
		}
		self& operator--() {
			--_it;
			return *this;
		}
		self operator--() {
			self tmp(_it--);
			return tmp;
		}
		Ref operator*() {
			return *_it;
		}
		Ptr operator->() {
			return _it;
		}
		bool operator==(const self& it) {
			return it._it == _it;
		}
		bool operator!=(const self& it) {
			return it._it != it;
		}
		
		Iterator _it;
	};
	//list 容器
	template <class T>
	class list {
	public:
		typedef ListNode<T> Node;
		typedef Iterator<T, T&, T*> iterator;
		typedef Iterator<T, const T&, const T*> const_iterator;
		typedef Reverse_Iterator<iterator, T&, T*> reverse_iterator;
		typedef Reverse_Iterator<const_iterator, const T&, const T*> const_reverse_iterator;

		//默认函数
		list();
		list(size_t n, const T& val = T());
		template <class InputIterator>
		list(InputIterator first, InputIterator last);
		list(const list<T>& lst);
		list<T>& operator=(const list<T>& lst);
		~list();

		//插入和删除
		void push_back(const T& val);
		void pop_back();
		void push_front(const T& val);
		void pop_front();
		iterator insert(iterator pos, const T& val);
		void insert(iterator pos, size_t n, const T& val);
		template <class InputIterator>
		void insert(iterator pos, InputIterator first, InputIterator last);
		iterator erase(iterator pos);
		iterator erase(iterator first, iterator last);

		//迭代器相关函数
		iterator begin();
		iterator end();
		const_iterator begin()const;
		const_iterator end()const;
		const_iterator cbegin()const;
		const_iterator cend()const;
		reverse_iterator rbegin();
		reverse_iterator rend();
		const_reverse_iterator rbegin()const;
		const_reverse_iterator rend()const;
		const_reverse_iterator crbegin()const;
		const_reverse_iterator crend()const;

		//访问元素函数
		T front()const;
		T back()const;

		//容器大小控制
		size_t size()const;
		void resize(size_t n, const T& val = T());
		bool empty()const;
		void clear();

		//容器操作函数
		template <class Compare = bool(const T&, const T&)>
		void sort(Compare comp = compare_sort);
		void splice(iterator pos, list<T>& lst);
		void splice(iterator pos, list<T>& lst, iterator it);
		void splice(iterator pos, list<T>& lst, iterator first, iterator last);
		void remove(const T& val);
		template <typename Compare>
		void remove_if(Compare comp = bool(const T&));

		template <class Compare = bool(const T&, const T&)>
		void unique(Compare comp = compare_unique);

		template <class Compare = compare_sort>
		void merge(list& lst, Compare comp);

		void reverse();

		void assign(size_t n, const T& val);
		template <class InputIterator>
		void assign(InputIterator first, InputIterator last);

		void swap(list& lst);

		template<class... Arg>
		iterator emplace(iterator pos, Arg&&... args);
		
	private:
		bool compare_sort(const T& val1, const T& val2) {
			return val1 <= val2;
		}
		bool compare_unique(const T& val1, const T& val2) {
			return val1 == val2;
		}
		Node* _node;		//头结点
	};
	//成员函数类外实现
	template <typename T>
	list<T>::list() :_node(nullptr) {
		_node = new Node;
		_node->_next = _node;
		_node->_prev = _node;
	}

	template <typename T>
	list<T>::list(size_t n, const T& val) :_node(nullptr) {
		_node = new Node;
		_node->_next = _node;
		_node->_prev = _node;
		resize(n, val);
	}
	
	template <typename T>
	template <typename InputIterator>
	list<T>::list(InputIterator first, InputIterator last) {
		_node = new Node;
		Node* prev = _node;
		for (InputIterator it = first; it != last; it++) {
			Node* cur = new Node(*it);
			prev->_next = cur;
			cur->_prev = prev;
			prev = cur;
		}
		prev->_next = _node;
		_node->_prev = prev;
	}

	template <typename T>
	list<T>::list(const list<T>& lst) {
		_node = new Node;
		_node->_next = _node;
		_node->_prev = _node;
		for (const auto& e : lst) {
			push_back(e);
		}
	}

	/*template <typename T>
	list<T>& list<T>::operator=(const list<T>& lst) {
		if (&lst != this) {
			clear();
			for (const auto& e : lst) {
				push_back(e);
			}
		}
		return *this;
	}*/

	template <typename T>
	list<T>& list<T>::operator=(const list<T>& lst) {
		if (&lst != this) {
			list<T> tmp(lst);
			::swap(_node, tmp._node);
		}
		return *this;
	}

	template <typename T>
	list<T>::~list() {
		clear();
		delete _node;
		_node = nullptr;
	}

	template <typename T>
	void list<T>::push_back(const T& val) {
		Node* new_node = new Node(val);
		_node->_prev->next = new_node;
		new_node->_prev = _node->_prev;
		_node->_prev = new_node;
		new_node->_next = _node;
	}

	template <typename T>
	void list<T>::pop_back() {
		if (!empty()) {
			Node* target = _node->_prev;
			_node->_prev = target->_prev;
			target->_prev->_next = _node;
			delete target;
			target = nullptr;
		}
	}

	template <typename T>
	void list<T>::push_front(const T& val) {
		Node* new_node = new Node(val);
		_node->_next->_prev = new_node;
		new_node->_next = _node->_next;
		new_node->_prev = _node;
		_node->_next = new_node;
	}

	template <typename T>
	void list<T>::pop_front() {
		if (!empty()) {
			Node* target = _node->_next;
			_node->_next = target->_next;
			target->_next->_prev = _node;
			delete target;
			target = nullptr;
		}
	}

	template <typename T>
	typename list<T>::iterator list<T>::insert(iterator pos, const T& val) {
		Node* new_node = new Node(val);
		Node* pos_node = pos._it;
		pos_node->_prev->_next = new_node;
		new_node->_prev = pos_node->_prev;
		pos_node->_prev = new_node;
		new_node->_next = pos_node;
		return iterator(new_node);
	}

	template <typename T>
	void list<T>::insert(iterator pos, size_t n, const T& val) {
		for (size_t i = 0; i < n; i++) {
			pos = insert(pos, val);
		}
	}

	template <typename T>
	template <typename InputIterator>
	void list<T>::insert(iterator pos, InputIterator first, InputIterator last) {
		for (InputIterator it = first; it != last; it++) {
			insert(pos, *it);
		}
	}

	template <typename T>
	typename list<T>::iterator list<T>::erase(iterator pos) {
		Node* pos_node = pos->_it;
		pos_node->_prev->_next = pos_node->_next;
		pos_node->_next->_prev = pos_node->_prev;
		Node* ret = pos_node->_next;
		delete pos_node;
		pos_node = nullptr;
		return iterator(ret);
	}

	template <typename T>
	typename list<T>::iterator list<T>::erase(iterator first, iterator last) {
		for (iterator it = first; it != last;) {
			it = erase(it);
		}
	}

	template <typename T>
	typename list<T>::iterator list<T>::begin() {
		return iterator(_node->_next);
	}

	template <typename T>
	typename list<T>::iterator list<T>::end() {
		return iterator(_node);
	}

	template <typename T>
	typename list<T>::const_iterator list<T>::begin()const {
		return const_iterator(_node->_next);
	}

	template <typename T>
	typename list<T>::const_iterator list<T>::end()const {
		return const_iterator(_node);
	}

	template <typename T>
	typename list<T>::const_iterator list<T>::cbegin()const {
		return const_iterator(_node->_next);
	}

	template <typename T>
	typename list<T>::const_iterator list<T>::cend()const {
		return const_iterator(_node);
	}

	template <typename T>
	typename list<T>::reverse_iterator list<T>::rbegin() {
		return reverse_iterator(iterator(_node->_prev));
	}

	template <typename T>
	typename list<T>::reverse_iterator list<T>::rend() {
		return reverse_iterator(iterator(_node));
	}

	template <typename T>
	typename list<T>::const_reverse_iterator list<T>::rbegin()const {
		return const_reverse_iterator(const_iterator(_node->_prev));
	}

	template <typename T>
	typename list<T>::const_reverse_iterator list<T>::rend()const {
		return const_reverse_iterator(const_iterator(_node));
	}

	template <typename T>
	typename list<T>::const_reverse_iterator list<T>::crbegin()const {
		return const_reverse_iterator(const_iterator(_node->_prev));
	}

	template <typename T>
	typename list<T>::const_reverse_iterator list<T>::crend()const {
		return const_reverse_iterator(const_iterator(_node));
	}

	template <typename T>
	T list<T>::front()const {
		assert(!empty());
		return _node->_next->_val;
	}
	template <typename T>
	T list<T>::back()const {
		assert(!empty());
		return _node->_next->_val;
	}

	template <typename T>
	size_t list<T>::size()const {
		Node* first = _node->_next;
		size_t size = 0;
		while (first != _node) {
			++size;
			first = first->_next;
		}
		return size;
	}

	template <typename T>
	void list<T>::resize(size_t n, const T& val) {
		if (size() <= n) {
			insert(end(), n - size(), val);
		}
		else {
			//未重载 iterator 的 - 操作,会报错
			erase(end() - size() + n, end());		
		}
	}

	template <typename T>
	bool list<T>::empty()const {
		return _node->_next == _node;
	}

	template <typename T>
	void list<T>::clear() {
		erase(begin(), end());
	}

	template <typename T>
	bool compare(const T& val1, const T& val2) {
		return val1 < val2;
	}
	template <typename T>
	template <typename Compare>
	void list<T>::sort(Compare comp) {
		//使用选择排序这里只交换元素值,不交换整个节点
		for (iterator first = begin(); first != end(); first++) {
			for (iterator it = first; it != end(); it++) {
				if (!comp(first._it->_val, it._it->_val)) {
					::swap(first._it->_val, it._it->_val);
				}
			}
		}
	}

	template <typename T>
	void list<T>::splice(iterator pos, list<T>& lst, iterator first, iterator last) {
		//insert(pos, first, last);		//error
		Node* first_prev = first->_it->_prev;
		Node* pos_node = pos->_it;
		for (iterator it = first; it != last; it++) {
			Node* it_node = it->_it;
			it_node->_prev = pos_node->_prev;
			pos_node->_prev->_next = it_node;
			it_node->_next = pos_node;
			pos_node->_prev = it_node;
		}
		//删除 lst 中已经拼接的元素
		first_prev->_next = last._it;
		last._it->_prev = first_prev;
	}

	template <typename T>
	void list<T>::splice(iterator pos, list<T>& lst, iterator it) {
		splice(pos, lst, it, it + 1);
	}

	template <typename T>
	void list<T>::splice(iterator pos, list<T>& lst) {
		splice(pos, lst.begin(), lst.end());
	}

	template <typename T>
	void list<T>::remove(const T& val) {
		for (iterator it = begin(); it != end(); it++) {
			if (*it == val) {
				erase(it);
			}
		}
	}

	template <typename T>
	template <typename Compare>
	void list<T>::remove_if(Compare comp) {
		for (iterator it = begin(); it != end(); it++) {
			if (comp(*it)) {
				erase(it);
			}
		}
	}

	template <typename T>
	template <typename Compare>
	void list<T>::unique(Compare comp) {
		for (iterator it = begin() + 1; it != end();) {
			iterator target = it++;
			if (comp(*it, *(it - 1))) {
				erase(target);
			}
		}
	}

	template <typename T>
	template <typename Compare>
	void list<T>::merge(list& lst, Compare comp) {
		iterator start = lst.begin();
		while (start != lst.end()) {
			iterator it = begin();
			while (it != end()) {
				if (comp(*start, *it)) {
					splice(it, lst, start);
					break;
				}
			}
			if (it == end()) {
				insert(end(), start, lst.end());
				break;
			}
			start++;
		}
	}

	template <typename T>
	void list<T>::reverse() {
		size_t size = size();
		Node* last = _node->_prev;
		Node* first = _node->_next;
		for (size_t i = 0; i < size; i++) {
			first->_prev = last;
			last->_next = first;
			first = last;
			last = last->_prev;
		}
		_node->_next = first;
		_node->_prev = last;
	}

	template <typename T>
	void list<T>::assign(size_t n, const T& val) {
		clear();
		resize(n, val);
	}

	template <typename T>
	template <typename InputIterator>
	void list<T>::assign(InputIterator first, InputIterator last) {
		clear();
		insert(begin(), first, last);
	}

	template <typename T>
	void list<T>::swap(list& lst) {
		::swap(_node, lst._node);
	}
}

test.cpp(测试)

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include "list.h"
using namespace yw;
int main() {
	list<int> lst;
	lst.push_back(1);
	lst.push_back(2);
	lst.push_back(3);
	lst.push_back(4);
	for (auto e : lst) {
		std::cout << e;
	}
	return 0;
}

说明:

  1. 本篇文章对 list 的实现并没有和前面 vector 和 string 一样,对每个接口进行详细的实现说明,因为其实现方法和前面相差不大

  2. 由于时间有限,该测试只是对模拟实现的 list 进行了编译运行,对于一些函数实现细节考虑欠缺


本篇文章到这里就结束啦,欢迎批评指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值