【C++】10.list

list这个迭代器是双向迭代器,与vector的迭代器具有很大的区别,主要在于双向迭代器不支持+- 操作
正由于list的双向迭代器,因此<algorithm>中的sort()函数无法使用,list单独实现了一个sort()函数,但效率极低。

一、list的介绍与使用

在这里插入图片描述

  1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
  2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向
    其前一个元素和后一个元素。
  3. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高
    效。
  4. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。
  5. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list
    的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间
    开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这
    可能是一个重要的因素)
    在这里插入图片描述

二、list的模拟实现

2.1 节点类

//结点
template<class T>
struct ListNode
{
	T _data;
	ListNode<T>* _prev;
	ListNode<T>* _next;

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

2.2 迭代器类

由于在遍历时需要实现++的操作,但是链表并不是连续的,因此需要对结点的行为进行重新定义,就有了这个类

//迭代器
 template<class T,class ref,class ptr>
 struct ListIterator
 {
	 typedef ListNode<T> Node;
	 typedef ListIterator self;

	 Node* _node;

	 ListIterator(Node* node):_node(node){}
	 self& operator++()
	 {
		 _node = _node->_next;
		 return *this;
	 }
	 self& operator--()
	 {
		 _node = _node->_prev;
		 return *this;
	 }
	 self& operator++(int)
	 {
		 Node* temp = *this;
		 _node = _node->_next;
		 return temp;
	 }
	 self& operator--(int)
	 {
		 Node* temp = *this;
		 _node = _node->_prev;
		 return temp;
	 }
	 bool operator!=(const self&  x)
	 {
		 return _node != x._node;
	 }
	 bool operator==(const self& x)
	 {
		 return _node == x._node;
	 }
	 ref operator*()
	 {
		 return _node->_data;
	 }
	 ptr operator->()
	 {
		 return &_node->_data;
	 }
 };

2.3 list类

//链表
template<class T>
class list
{
	typedef ListNode<T> Node;
	typedef ListIterator<T,T&,T*> iterator;
	typedef ListIterator<T,const T&,const T*> const_iterator;
private:
	Node* _head;
public:
	void empty_head()
	{
		_head = new Node();
		_head->_next = _head;
		_head->_prev = _head;
	}
	list()
	{
		empty_head();
	}
	list(const list& lt)
	{
		empty_head();
		for (const auto& e : lt)
		{
			push_back(e);
		}
	}
	list(initializer_list<T> il)
	{
		empty_head();
		for (const auto& e : il)
		{
			push_back(e);
		}
	}
	list<T>& operator=(list<T> lt)
	{
		swap(_head, lt._head);
		return *this;
	}
	void clear()
	{
		auto it = begin();
		while (it != end())
		{
			it=erase(it);//连续的删除,可能造成迭代器失效
		}
	}
	~list()
	{
		clear();
		delete _head;
		_head = nullptr;
	}
	void push_back(const T& x)
	{
		/*Node* newnode = new Node(x);
		Node* tail = _head->_prev;

		tail->_next = newnode;
		newnode->_prev = tail;
		newnode->_next = _head;
		_head->_prev = newnode;*/
		insert(end(), x);
	}
	void pop_back()
	{
		erase(--end());
	}
	void push_front(const T& x)
	{
		insert(begin(), x);
	}
	void pop_front()
	{
		erase(begin());
	}
	iterator begin()
	{
		return iterator(_head->_next);
	}
	iterator end()
	{
		return iterator(_head);
	}
	const_iterator begin() const
	{
		return const_iterator(_head->_next);
	}
	const_iterator end() const
	{
		return const_iterator(_head);
	}
	iterator insert(iterator pos, const T& x)
	{
		Node* cur = pos._node;
		Node* prev = cur->_prev;

		Node* newnode = new Node(x);

		newnode->_prev = prev;
		prev->_next = newnode;
		cur->_prev = newnode;
		newnode->_next = cur;
		return iterator(newnode);
	}
	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 next;
		
	}
};
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中的list容器具有自带的sort成员函数,可以用于对list中的元素进行排序。list::sort函数采用基于指针的方式排序,因此排序后的迭代器仍然有效。与算法函数中的sort函数类似,list::sort函数可以按升序或降序对元素进行排序。 以下是使用list::sort函数对一个包含整数的list进行排序的示例代码: ``` #include <iostream> #include <list> using namespace std; bool comp(int a, int b) { return a > b; } int main() { list<int> l; for (int i = 0; i < 5; i++) { int temp; cin >> temp; l.push_back(temp); } l.sort(); // 默认按升序排序 for (list<int>::iterator it = l.begin(); it != l.end(); it++) { cout << *it; } l.sort(comp); // 按降序排序 for (list<int>::iterator it = l.begin(); it != l.end(); it++) { cout << *it; } return 0; } ``` 在这个例子中,我们首先使用默认的sort函数将list中的元素按升序排序,然后使用自定义的comp函数将list中的元素按降序排序。在输出结果时,我们遍历list并打印每个元素。注意,在使用sort函数后,list中的元素已经被重新排序。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++ STL list.sort( ) 高级用法](https://blog.csdn.net/m0_46628923/article/details/107271405)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C++排序函数sort()的使用](https://blog.csdn.net/summer00072/article/details/80609782)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值