2024年C C++最全【C++】list_c+(2),真服了

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

而在使用迭代器遍历时,需要使用的 *、!=、++、–、-> 等操作符都需要重载。

template<class T, class Ref, class Ptr> // 三个模板参数分别表示 T类型,T类型引用,T类型指针
	struct __list_iterator
	{
		typedef ListNode<T> Node;
		typedef __list_iterator<T, Ref, Ptr> self;
		Node* _node; // 定义节点指针变量
		__list_iterator(Node* x) // 节点构造函数
			:_node(x)
		{}                       // list迭代器不需要自己写析构函数、拷贝构造、赋值重载
                                 // 使用默认生成的浅拷贝就可以,因为迭代器不需要释放节点

		Ref operator*()
		{
			return _node->_data; // 重载运算符 * ,返回该节点的_data
		}
		Ptr operator->()
		{
			return &_node->_data; // 重载运算符 ->, 如果_date中存的是自定义类型,访问时需使用->
		}
		self operator++()
		{
			_node = _node->_next; // 重载运算符 前置++,返回下一个节点
			return *this;
		}
		self operator++(int)
		{
			self tmp(*this);
			_node = _node->_next; // 重载运算符 后置++
			return *this;
		}
		self operator--()
		{
			_node = _node->_prev; // 重载运算符 前置--,返回前一个节点
			return *this;
		}
		self operator--(int)
		{
			self tmp(_node);
			_node = _node->_prev; // 重载运算符 后置--
			return tmp;
		}

		bool operator!=(const self& it)const
		{
			return _node != it._node; // 重载运算符 !=,比较当前节点与it节点是否相等
		}

		bool operator==(const self& it)const
		{
			return _node == it._node; // 重载运算符 ==
		}
	};

2.3. end()、begin()

        typedef __list_iterator<T, T&, T*> iterator; 
		typedef __list_iterator<T, const T&, const T*> const_iterator; // const迭代器
                               // 这里传入的三个模板参数可以很好的区分普通迭代器与const迭代器
		iterator begin()
		{
			return iterator(_head->_next); // begin()返回的是迭代器,所以使用头节点的下一个位置构造迭代器节点
		}

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

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

		const_iterator end()const
		{
			return const_iterator(_head);
		}

2.4 构造函数、析构函数、赋值运算符重载

        list()
		{
			_head = new Node();   // 空构造头节点
			_head->_next = _head;
			_head->_prev = _head;
		}

		~list()
		{
			clear(); // 清空链表节点
			delete _head; // 释放头节点
			_head = nullptr;
		}

		void clear() // 清空链表出头节点外其他节点
		{
			iterator it = begin();
			while (it != end()) // 利用迭代器遍历删除
			{
				Node* del = it._node;
				++it;
				erase(del);
				
			}
		}

		template <class InputIterator>
		list(InputIterator first, InputIterator last) // 迭代器区间构造
		{
			_head = new Node();
			_head->_next = _head;
			_head->_prev = _head;

			while (first != last)
			{
				push_back(*first); // 因为重载过迭代器的*运算符,可以得到该位置的_data
				++first;           // 然后通过迭代器遍历将每个值尾插到链表上
			}
		}

		list(const list<T>& lt) // 拷贝构造现代写法
		{
			_head = new Node();   // 这里必须要先将空链表初始化,否则后面交换后释放tmp会导致释放未开辟的空间,导致程序崩溃
			_head->_next = _head;
			_head->_prev = _head;
			list<T> tmp(lt.begin(), lt.end()); // 利用被拷贝链表的迭代器构造临时链表
			swap(_head, tmp._head); // 交换头节点指针
		}


		list<T>& operator=(list<T> lt) // 赋值运算符重载
		{
			swap(_head, lt._head); // 传参时传临时对象,直接交换
			return *this;
		}

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

2.5. 其他常用接口

        // 头插
        void push_front(T val)
		{
			insert(begin(), val); // 复用insert
		}

        // 尾插
		void push_back(T val)
		{
			/*Node* newnode = new Node(val);
			Node* tail = _head->_prev;
			tail->_next = newnode;
			newnode->_prev = tail;
			newnode->_next = _head;
			_head->_prev = newnode;*/

			insert(end(), val);
		}

        // 头删
		void pop_front()
		{
			erase(--end());
		}

        // 尾删
		void pop_back()
		{
			erase(begin());
		}

        // pos位置前插入
		iterator insert(iterator pos,const T& val)
		{
			Node* cur = pos._node;
			Node* newnode = new Node(val);
			cur->_prev->_next = newnode;
			newnode->_prev = cur->_prev;
			newnode->_next = cur;
			cur->_prev = newnode;
			return iterator(newnode);
		}
        
        // 删除pos位置
		iterator erase(iterator pos)
		{
			assert(pos != end());
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;


![img](https://img-blog.csdnimg.cn/img_convert/8361d81aec18ca9c6f78ab5a041acace.png)
![img](https://img-blog.csdnimg.cn/img_convert/cd92b9cdbc8105b69af38e8d8cb337fa.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

转存中...(img-XsSg2bnd-1715532664473)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值