2024年最全【C++】list_c+(1),头条C C++面试算法

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

	{}                       // 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()


![](https://img-blog.csdnimg.cn/3145460128824a6b93c110fc09d68fef.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6aOO57un57ut5ZC5VFQ=,size_20,color_FFFFFF,t_70,g_se,x_16)


 



    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;
		prev->_next = next;
		next->_prev = prev;
		delete cur;
		return iterator(next);
	}


### 2.6. 反向迭代器(了解)


反向迭代器与正向迭代器不同,它复用了正向迭代器的一些接口,且begin()和end()位置与正向迭代器是对称的。


![](https://img-blog.csdnimg.cn/7fa3530cda944d52aeb1a66087903b65.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6aOO57un57ut5ZC5VFQ=,size_20,color_FFFFFF,t_70,g_se,x_16)​​​​​​​ 


![img](https://img-blog.csdnimg.cn/img_convert/c5ff12b7d1dcecbc02627820ef0b98c8.png)
![img](https://img-blog.csdnimg.cn/img_convert/ef7c19f66115b28f021e4d5edf61a309.png)

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

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

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

片转存中...(img-Vg4KtP5k-1715755613894)]

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值