C++自写list类

文章目录

成员变量

  1._head指向头节点。

  2._size统计有效节点个数。

cpp 复制代码
private:
	Node* _head;
	size_t _size;   
};

创建节点

  1.T是类型参数,使用模板可以存储任意类型的参数。

  2._data存储数据。

  3._next指向下一个节点的指针。

  4._prev指向前一个节点的指针。

  5.使用初始化列表进行初始化,const T& data = T(): 参数默认使用类型T的默认构造函数创建的对象。

cpp 复制代码
template<class T>
struct list_node {
	T _data;
	list_node<T>* _next;
	list_node<T>* _prev;

	list_node(const T& data = T())
		:_data(data)
		, _next(nullptr)
		, _prev(nullptr)
	{
	}
};

操作符重载

  1.Ref是引用类型,可以是T&,const T&.

  2.Ptr是指针类型,可以是T*,const T*.

  3.Node节点类型。

  4.Self迭代器的自身类型。

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->_data;
	}
	
	//返回指向数据的指针
	Ptr operator->() {
		return &(_node->_data);
	}
	Self operator++() {
		_node = _node->_next;
		return *this;
	}
	Self operator++(int) {
		_node = _node->_next;
		return *this;
	}
	Self operator--() {
		_node = _node->_prev;
		return *this;
	}

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

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

	friend ostream& operator<<(ostream& out, const Self& it) {
		out << it._node_data << endl;
		return out;
	}
};

list主要函数操作实现

  1.iterator定义普通迭代器操作。

  2.const_iterator定义const迭代器操作。

  3.begin()函数是哨兵位头节点指向的下一个位置。

  4.end()函数指向哨兵位头节点。

  5.在默认构造函数list()中调用empty_init()初始化空列表。

  6.初始化列表构造函数目的是为了支持 list mylist = {1, 2, 3, 4}; 语法。

  7.拷贝构造函数,深拷贝,不会影响原始列表。

  8.操作符重载,巧妙借助了swap函数交换当前变量和临时对象啊,临时对象在函数结束时自动销毁。

  9.在析构函数中,先清除所有元素,在释放头节点。

  10.push_back()函数进行尾插。

  11.insert()在当前迭代器的位置插入新的数据,然后返回新的迭代器的位置,防止迭代器失效。

cpp 复制代码
template<class T>
class list {
	typedef list_node<T> Node;
public:

	/*typedef list_iterator<T> iterator;
	typedef list_const_iterator<T> const_iterator;*/

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

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

	iterator end() {
		return iterator(_head);
	}

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

	const_iterator end() const {
		return _head;
	}

	void empty_init() {
		//传匿名对象
		_head = new Node(T());
		_head->_next = _head;
		_head->_prev = _head;
		_size = 0;
	}

	list() {
		empty_init();
	}

	list(initializer_list<T> il) {
		empty_init();
		for (auto& e : il) {
			push_back(e);
		}
	}

	//lt2(lt1) 
	list(const list<T>& lt) {
		empty_init();   //初始化lt2的头节点
		for (auto& e : lt) {
			push_back(e);
		}
	}

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

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

	void clear() {
		auto it = begin();
		while (it != end()) {
			it = erase(it);
		}
	}

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


	void push_back(const T& x) {
		Node* newnode = new Node(x);
		//尾结点
		Node* tail = _head->_prev;
		tail->_next = newnode;
		newnode->_prev = tail;
		_head->_prev = newnode;
		newnode->_next = _head;
		++_size;
	}
	void push_front(const T& x) {
		insert(begin(), x);
	}

	void pop_back() {
		Node* cur = _head->_prev;
		Node* prev = cur->_prev;
		Node* next = _head;
		prev->_next = next;
		_size--;
		erase(--end());
	}
	void pop_front() {
		erase(begin());
		_size--;
	}
	iterator insert(iterator it, const T& x) {
		Node* cur = it._node;

		Node* newnode = new Node(x);
		newnode->_next = cur;
		newnode->_prev = cur->_prev;
		cur->_prev->_next = newnode;
		cur->_prev = newnode;
		++_size;

		return newnode;
	}

	iterator erase(iterator pos) {
		assert(pos != end());
		Node* cur = pos._node;
		Node* next = cur->_next;

		cur->_prev->_next = cur->_next;
		cur->_next->_prev = cur->_prev;

		delete pos._node;
		_size--;

		return next;
	}

	size_t size() const {
		return _size;
	}

	bool empty() const {
		return _size==0;
	}

private:
	Node* _head;
	size_t _size;
};

Container容器

cpp 复制代码
template<class Container>
void printf_container(const Container& con) {
	//const iterator  迭代器本身不能修改
	//const_iterator 迭代器指向的内容不能修改
	typename Container::const_iterator it = con.begin();
	while (it != con.end()) {
		//这里使用了const_iterator迭代器,按理来说迭代器指向的内容不能修改
		//会编译错误,但是这里没有报错
		//进行了按需实例化,函数没有调用就没有检查细节
		// 
		//*it += 10;

		cout << *it << " ";
		++it;
	}
	cout << endl;
}

觉得我回答有用的话,记得点个关注哟!谢谢支持!

相关推荐
用户8055336980310 小时前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
BadBadBad__AK1 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
卷无止境1 天前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
卷无止境1 天前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端
郝学胜_神的一滴2 天前
CMake 30:循环语法全解|foreach_while双循环精讲、迭代技巧与实战避坑指南
c++·cmake
卷无止境4 天前
C++ 的Eigen 库全解析
c++
卷无止境4 天前
现代 C++特性大盘点:一门脱胎换骨的老语言
c++·后端
郝学胜_神的一滴4 天前
CMake 27:缓存变量的特性、语法、类型与实操全解
c++·cmake
博客18006 天前
酷宝的使用方法,超好用的免费界面库,C++、MFC可用
c++·mfc·界面库·库来帮·酷宝
郝学胜_神的一滴6 天前
CMake 026:属性体系精讲、四大作用域全解 & 实战代码落地
c++·cmake