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

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

相关推荐
王老师青少年编程14 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【哈夫曼贪心】:合并果子
c++·算法·贪心·csp·信奥赛·哈夫曼贪心·合并果子
叼烟扛炮14 小时前
C++第二讲:类和对象(上)
数据结构·c++·算法·类和对象·struct·实例化
样例过了就是过了16 小时前
LeetCode热题100 最长公共子序列
c++·算法·leetcode·动态规划
谭欣辰16 小时前
C++ 排列组合完整指南
开发语言·c++·算法
橙子也要努力变强17 小时前
信号捕捉底层机制-机理篇2
linux·服务器·c++
盐焗鹌鹑蛋17 小时前
【C++】stack和queue类
c++
郝学胜-神的一滴18 小时前
罗德里格斯旋转公式(Rodrigues‘ Rotation Formula)完整推导
c++·unity·godot·图形渲染·three.js·unreal
lzh2004091918 小时前
深入理解进程:从PCB内核结构到写时拷贝的底层实战
linux·c++
aseity19 小时前
跨平台项目中QString 与 非Qt 跨平台动态库在字符集上的一个实用的互操作约定.
c++·经验分享
CN-Dust19 小时前
【C++】while语句例题专题
数据结构·c++·算法