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

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

相关推荐
波特率11520014 小时前
const关键字与函数的重载
开发语言·c++·函数重载
干啥啥不行,秃头第一名15 小时前
C++20概念(Concepts)入门指南
开发语言·c++·算法
2301_8073671915 小时前
C++中的解释器模式变体
开发语言·c++·算法
2301_8194143017 小时前
C++与区块链智能合约
开发语言·c++·算法
不想看见40417 小时前
Valid Parentheses栈和队列--力扣101算法题解笔记
开发语言·数据结构·c++
老约家的可汗17 小时前
C/C++内存管理探秘:从内存分布到new/delete的底层原理
c语言·c++
天赐学c语言18 小时前
Linux - 应用层自定义协议与序列/反序列化
linux·服务器·网络·c++
计算机安禾18 小时前
【C语言程序设计】第37篇:链表数据结构(一):单向链表的实现
c语言·开发语言·数据结构·c++·算法·链表·蓝桥杯
阿贵---18 小时前
C++构建缓存加速
开发语言·c++·算法
波特率11520018 小时前
C++当中is-a(继承)与has-a(成员对象)的辨析与使用指南(包含实际工程当中的使用示例)
c++·ros·串口通信