【C++链表】

目录

前言

最近用C++写了一下list的基本功能,感触颇深。本以为会跟之前用C写list一样会很轻松,没想到更难了。要考虑的东西跟多了,而且模板报错真的太恶心了(小小吐槽一下,其实就是自己学的不够扎实,还得练呐)。下面的内容是我自己在写链表时的顺序及注意点。

一、搭建链表实现的框架

二、链表的构造函数

当把一个框架搭建好后,第一步就是写的构造函数。

三、链表的尾插

构造函数写完后就要开始往链表里插入数据了,所以第三步我开始写链表的尾插(这里都是比较简单的跟之前C语言没什么两样)。我懒得画图解释了,直接上代码。

复制代码
void push_back(const T& val)
{
	Node* newnode = new Node(val);
	Node* tail = _head->_prev;

	//链接
	tail->_next = newnode;
	newnode->_prev = tail;

	newnode->_next = _head;
	_head->_prev = newnode;
}

四、链表的遍历(重点)

迭代器的遍历

先看看库实现的链表我们是怎么拿过来用的。

为了完成跟库里一样,我们还需要设计迭代器。

重载*、++其实很简单。但是重载!=有个比较坑的地方。

const修饰的迭代器

首先要清楚我们期望的const修的的迭代器是具有怎么的功能。

我们期望被const修饰过的迭代器指向的内容不要被修改,但是可以通过重载的++修改本身。

那这样行不行?如:

cpp 复制代码
typedef const _list_iterator<T> const_iterator;


五、代码实现

其他的功能其实都不难,都很好写。所以不想画图解释了,直接上代码。

cpp 复制代码
#pragma once
#include<iostream>
using namespace std;
namespace Ting
{
	template<class T>
	struct _list_node
	{
		_list_node<T>* _prev;
		_list_node<T>* _next;
		T _val;

		//构造函数
		_list_node(const T& val = T())
			:_next(nullptr)
			, _prev(nullptr)
			, _val(val)
		{}
	};

	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)
		{}
		bool operator!=(const self& it)//这个const有说法
		{
			return _node != it._node;
		}
		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}
		self operator++(int)
		{
			_list_iterator<T> temp(*this);
			_node = _node->_next;
			return temp;
		}
		Ref operator*()
		{
			return _node->_val;
		}
		Ptr operator->()
		{
			return &(_node->_val);
		}
	};

	template<class T>
	class _list
	{
		typedef _list_node<T> Node;
	public:
		typedef _list_iterator<T,T&,T*> iterator;
		//如何设计const迭代器
		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;
		}

		_list()
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
		}
		
		void push_back(const T& val=T())
		{
			Node* newnode = new Node(val);
			Node* tail = _head->_prev;

			//链接
			tail->_next = newnode;
			newnode->_prev = tail;

			newnode->_next = _head;
			_head->_prev = newnode;
		}

		void push_front(const T& val = T())
		{
			insert(begin(), val);
		}

		void pop_back()
		{
			Node* tail = _head->_prev;
			Node* newtail = tail->_prev;

			_head->_prev = newtail;
			newtail->_next = _head;
			
		}

		void pop_front()
		{
			erase(begin());
		}

		iterator insert(iterator pos, const T& val = T())
		{
			Node* cur = pos._node;
			Node* pre = cur->_prev;
			Node* newnode =new Node(val);

			pre->_next = newnode;
			newnode->_prev = pre;

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

			return newnode;
		}

		iterator erase(iterator pos)
		{
			Node* cur = pos._node;
			Node* pre = cur->_prev;
			Node* next = cur->_next;

			pre->_next = next;
			next->_prev = pre;
			delete cur;

			return next;
		}

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

		//拷贝构造
		_list(_list<T>& lt)
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;

			iterator it = lt.begin();
			while (it != lt.end())
			{
				push_back(*it);
				++it;
			}
		}

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

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

		~_list()
		{
			clear();
		}
	private:
		Node* _head;
	};
}
相关推荐
Mr_WangAndy1 小时前
C++数据结构与算法_线性表_数组_概念动态数组,刷题
c++·二分查找·数组刷题·数组字符串逆序·零移动·有序数组的平方
阿猿收手吧!1 小时前
【C++】jthread:优雅终止线程新方案
开发语言·c++
十五年专注C++开发2 小时前
C++中各平台表示Debug的宏
开发语言·c++·debug
阿猿收手吧!4 小时前
【C++】Ranges:彻底改变STL编程方式
开发语言·c++
Polaris北5 小时前
第二十三天打卡
c++
船神丿男人6 小时前
C++:STL string(一)
开发语言·c++
程序员zgh6 小时前
Linux 内存管理单元 MMU
linux·运维·服务器·c语言·开发语言·c++
Smart-Space7 小时前
将copilot键映射为右control - 参考powertoys实现
c++
Trouvaille ~7 小时前
【Linux】TCP协议基础与连接管理详解:从三次握手到四次挥手
linux·运维·服务器·网络·c++·网络协议·tcp/ip
想做功的洛伦兹力17 小时前
2026/2/12日打卡
开发语言·c++·算法