C++ list容器详解

list详解

概念

list的底层其实是一个双向循环链表,因此他不支持随机访问,但是在插入和删除上的效率很高,但是排序效率会低一些

使用

1,初始化
在这里插入图片描述
尾插:push_back
在这里插入图片描述
尾删:pop_back
在这里插入图片描述
头插:push_front
在这里插入图片描述
头删:pop_front
在这里插入图片描述
获取头部和尾部元素的引用
如果修改通过front和back的返回值,list内部的元素也会被修改
在这里插入图片描述

在这里插入图片描述
迭代器:(迭代器是一个类似于指针的东西,可以通过解引用去访问里面的数据,改变迭代器的数据同时也会改变容器内的数据)
1,正向迭代器(begin,end)
在这里插入图片描述
使用迭代器遍历
在这里插入图片描述

2,反向迭代器(rbegin,rend)
在这里插入图片描述
注意:反向迭代器的rbegin是返回最后一个元素的位置,如果向往前遍历,不是用–去操作,而是++,同样rend如果要往后遍历不是用++,而是用–
在这里插入图片描述

获取有效元素个数:size
在这里插入图片描述
在指定位置之前插入数据:insert
在这里插入图片描述

删除指定位置数据:erase
在这里插入图片描述

删除指定数据:remove
在这里插入图片描述
排序:sort
在这里插入图片描述
清空所有数据和判空:empty
在这里插入图片描述
交换两个list的数据:swap
在这里插入图片描述

迭代器失效问题

在这里插入图片描述
首先我们来看lt中的数据:
在这里插入图片描述
现在it指向第一个数据,然后把1删除掉:
在这里插入图片描述
在删除1后,第一个元素就变成了2,那么此时迭代器it是指向2,还是失效了?
来验证一下:
在这里插入图片描述
可以看到,直接报错,因为list是一个链表,所有删除数据后,第二个数据到第一的位置,但是迭代器记录的是第一个位置的地址,1被删除后,开辟的空间也被释放掉了,因此迭代器会失效

但是erase函数有一个返回值,在使用迭代器作为参数删除一个数据后,会返回这个数据的下一位置的迭代器
在这里插入图片描述
如果是删除最后一个数据,返回的是什么呢?
在这里插入图片描述
答案是返回最后一个元素的下一个位置,但是这个位置没有数据,因此直接访问会报错,但是如果–这个迭代器就可以得到最后一个数据,删除最后一个数据6后,最后一个数据变成了5,我们来验证一下:
在这里插入图片描述

模拟实现

#pragma once
#include<iostream>
#include<list>
#include<assert.h>
#include"iterator.h"

using namespace std;

namespace ys
{
	template<class T>
	struct list_node
	{
		list_node<T>* _next;
		list_node<T>* _prev;
		T _data;

		list_node(const T& x = T())
			:_next(nullptr)
			, _prev(nullptr)
			, _data(x)
		{}
	};

	//迭代器
	template<class T,class Ref,class Ptr>
	struct __list_iterator
	{
		typedef list_node<T> node;
		typedef __list_iterator self;
		node* _node;

		__list_iterator(node* n)
			:_node(n)
		{
			
		}
		
		Ref operator *()
		{
			return _node->_data;
		}

		T& operator ->()
		{
			return _node->_data;
		}

		bool operator !=(const self& x)
		{
			return _node != x._node;
		}

		bool operator ==(const self& x)
		{
			return _node == x._node;
		}

		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		//后置++
		self& operator++(int)
		{
			self tmp = _node;
			_node = _node->_next;
			return tmp;
		}

		self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}

		//后置--
		self& operator--(int)
		{
			self tmp = _node;
			_node = _node->_prve;
			return tmp;
		}
	};

	//反向迭代器


	cosnt迭代器
	//template<class T>
	//struct __list_const_iterator
	//{
	//	typedef list_node<T> node;
	//	typedef __list_const_iterator self;
	//	node* _node;

	//	__list_const_iterator(node* n)
	//		:_node(n)
	//	{

	//	}

	//	const T& operator *()
	//	{
	//		return _node->_data;
	//	}

	//	bool operator !=(const self& x)
	//	{
	//		return _node != x._node;
	//	}

	//	bool operator ==(const self& x)
	//	{
	//		return _node == x._node;
	//	}

	//	self& operator++()
	//	{
	//		_node = _node->_next;
	//		return *this;
	//	}

	//	//后置++
	//	self& operator++(int)
	//	{
	//		self tmp = _node;
	//		_node = _node->_next;
	//		return tmp;
	//	}

	//	self& operator--()
	//	{
	//		_node = _node->_prve;
	//		return *this;
	//	}

	//	//后置--
	//	self& operator--(int)
	//	{
	//		self tmp = _node;
	//		_node = _node->_prve;
	//		return tmp;
	//	}
	//};

	template<class T>
	class list
	{
		typedef list_node<T> node;


	public:
		typedef __list_iterator<T,T&, T*> iterator;
		typedef __list_iterator<T,const T&,const T*> const_irerator;
		typedef ys1::ReverseIterator<iterator, T&, T*> reverse_iterator;

		//typedef __list_const_iterator<T> const_irerator;

		//空初始化
		void empty_init()
		{
			_head = new node;
			_head->_next = _head;
			_head->_prev = _head;
		}
		list()
		{
			empty_init();
		}

		//迭代器区间初始化
		template <class Iterator>
		list(Iterator first, Iterator last)
		{
			empty_init();
			while (first != last)
			{
				push_back(*first);
				first++;
			}
		}

		//交换
		void swap(list<T>& tmp)
		{
			std::swap(_head, tmp._head);
		}

		list(const list<T>& lt)
		{
			empty_init();
			//创建一个list作为中间层交换
			list<T> ptr(lt.begin(),lt.end());

			swap(ptr);
		}

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

		//析构
		~list()
		{
			clear();
			delete _head;
			_head = nullptr;
		}

		//清空所有数据
		void clear()
		{
			iterator i = begin();
			while (i != end())
			{
				erase(i++);
			}
		}

		//迭代器
		iterator begin()
		{
			/*iterator it(_head->_next);
			return it;*/
			return iterator(_head->_next);
		}

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

		//cosnt迭代器
		const_irerator cbegin() const
		{
			/*iterator it(_head->_next);
			return it;*/
			return const_irerator(_head->_next);
		}

		const_irerator cend() const
		{
			return const_irerator(_head);
		}

		//反向迭代器
		reverse_iterator rbegin()
		{
			return reverse_iterator(end());
		}

		reverse_iterator rend()
		{
			return reverse_iterator(begin());
		}

		void push_back(const T& val)
		{
			//找到尾部节点
			node* x = _head->_prev;

			//创建新节点
			node* ptr = new node;
			ptr->_data = val;

			x->_next = ptr;
			ptr->_prev = x;
			ptr->_next = _head;
			_head->_prev = ptr;


		}

		//使用迭代器插入
		void insert(iterator pos, const T& x)
		{
			node* prve = pos._node->_prev;
			node* nod = pos._node;

			node* ptr = new node(x);

			prve->_next = ptr;
			ptr->_prev = prve;
			ptr->_next = nod;
			nod->_prev = ptr;

		}

		//迭代器删除
		iterator erase(iterator pos)
		{
			assert(pos != end());
			node* prve = pos._node->_prev;
			node* next = pos._node->_next;

			prve->_next = next;
			next->_prev = prve;

			delete pos._node;
			return iterator(next);
		}

		//头删
		void pop_front()
		{
			erase(begin());
		}

		//尾删
		void pop_back()
		{
			erase(end()--);
		}

		//头插
		void push_front(const T& x)
		{
			insert(begin(),x);
		}

	private:
		node* _head;
	}
	;
	
}

//迭代器:

#pragma once

namespace ys1
{
	template<class iterator,class Ref, class Ptr>
	struct ReverseIterator
	{
		typedef ReverseIterator<iterator, Ref, Ptr> Self;
		iterator _cur;

		ReverseIterator(iterator it)
			:_cur(it)
		{
			
		}

		Ref operator*()
		{
			iterator tmp = _cur;
			--tmp;
			return *tmp;
		}

		Self& operator++()
		{
			--_cur;
			return *this;
		}

		Self& operator--()
		{
			++_cur;
			return *this;
		}

		bool operator!=(const Self& s)
		{
			return _cur != s._cur;
		}

	};
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值