Stl中list容器解析--C++

目录

前言

list功能一览表

list结构框架

list迭代器

基本框架

* 重载

-> 重载

++ 重载

-- 重载

!= 重载

list功能模拟

最初模板

begin()

end()

insert()

erase()

push_back()

push_front()

pop_back()

pop_front()

clear()

swap()

= 重载

无参构造

区间构造

拷贝构造

析构

小结


前言

list容器与前面的vector容器很大的区别在与list是以链表为基本结构进行数据的存储的:即空间不连续存储。因此list容器的学习重点在于迭代器的理解和掌握。

list功能一览表

list结构框架

template<class T>
struct list_node   //节点结构体:双链表
{
	list_node<T>* _next;
	list_node<T>* _prev;
	T _data;
	list_node(const T& val=T())  //构造函数
		:_next(nullptr)
		,_prev(nullptr)
		,_data(val)
	{}
};

template<class T>
class list
{
	typedef list_node<T> Node;
private:
	Node* _head;  //成员变量只有头节点
public:
    /.../
}

从上面的的结构可以看出,如果我们对于迭代器做出各种操作例如 * 、-> 、++ 、-- 等时,是无法直接像内置类型数据那样直接正常使用的,因此我们要想达到同样的效果,就要去自己实现这些操作符的重载。

list迭代器

基本框架

template<class T, class Ref, class Ptr> //传三个模板参数是为了将const迭代器与
struct __list_iterator                  //非const迭代器糅合在一起
{
	typedef list_node<T> Node;
	typedef __list_iterator<T, Ref, Ptr> self;
	Node* _node;                         //迭代器成员还是只有一个节点_node
	__list_iterator(Node* node)          //构造函数
		:_node(node)
	{}
};

* 重载

Ref operator*()   //Ref后面可以替换成T& 或 const T&
{
	return _node->_data;
}

-> 重载

Ptr operator->()   //Ptr后面可以替换成T* 或 const T*
{
	return &_node->_data;
}

++ 重载

使迭代器指向下一个节点

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


self& operator++(int) //后置++,用多写一个int参数来区分,实际使用时不用传参
{
	self tmp(*this);
	_node = _node->_next;
	return tmp;
}

-- 重载

使迭代器指向上一个节点

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


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

!= 重载

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

list功能模拟

最初模板

template<class T>
class list
{
	typedef list_node<T> Node;
private:
	Node* _head;
public:
	typedef __list_iterator<T, T&, T*> iterator;  //迭代器
	typedef __list_iterator<T, const T&, const T*> const_iterator;//const迭代器
}

begin()

iterator begin()
{
	return iterator(_head->_next);
}

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

end()

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

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

insert()

iterator insert(iterator pos, const T& val)
{
	Node* newnode = new Node(val);//创建新节点
	Node* cur = pos._node;        //当前节点
	Node* prev = cur->_prev;      //前一节点
	//  prev  newnode  cur  最终三个节点的位置
    prev->_next = newnode; 
	newnode->_prev = prev;
	newnode->_next = cur;
	cur->_prev = newnode;
	
    return iterator(newnode);
}

erase()

iterator erase(iterator pos)
{
	assert(pos != end());//不能删除哨兵位节点
	Node* cur = pos._node;//当前节点
	Node* prev = cur->_prev;//前一节点
	Node* next = cur->_next;//后一节点
    //prev   next   最终节点位置
	prev->_next = next;
	next->_prev = prev;
    //删除当前节点
	delete cur;
    //返回删除位置的下一位置的迭代器
	return iterator(next);
}

push_back()

void push_back(const T& val)
{
	insert(end(), val);//复用insert()函数
}

push_front()

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

pop_back()

void pop_back()
{
	erase(--end());
}

pop_front()

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

clear()

函数功能:清除当前list内的数据

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

swap()

函数功能:交换list内容

void swap(list<T>& lt)
{
	std::swap(_head, lt._head);//交换头节点即可
}

= 重载

list<T>& operator=(list<T> lt)
{
	swap(lt);//由于lt是深度拷贝构造而来,因此直接调用swap函数对原参数没影响
	return *this;
}

无参构造

void empty_init()//创建哨兵位头节点
{
	_head = new Node();
	_head->_next = _head;
	_head->_prev = _head;
}
list()
{
	empty_init();
}

区间构造

template<class InputIterator>
list(InputIterator first, InputIterator last)
{
	empty_init();
	while (first != last)
	{
		push_back(*first);
		++first;
	}
}

拷贝构造

list(const list<T>& lt)
{
	empty_init();
	list<T> tmp(lt.begin(), lt.end());//先利用区间构造tmp再与*this进行交换
	swap(tmp);
}

析构

~list()
{
	clear();
	delete _head;//最后的头节点也删除
	_head = nullptr;
}

小结

list容器的特点就在于迭代器,其他的内容基本都和其他容器的核心思想相同。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STL是指标准模板库(Standard Template Library),它是C++语言的一部分,提供了一系列的模板类和函数,用于支持通用的数据结构和算法。STL的目标是提供高效、可重用和可扩展的组件,以便开发人员能够更轻松地编写高质量的代码。STL包含了许多常见的数据结构,如vector、list、set、map等,以及各种算法,比如排序、查找、遍历等。通过使用STL,开发人员可以更加高效地处理各种数据结构和算法的问题,提高代码的开发效率和质量。 在STL,我们可以使用各种容器来存储和管理数据。例如,我们可以使用std::map来创建一个键值对的映射,其每个键都有一个与之相关联的值。下面是一个示例代码,展示了如何创建和使用一个std::map对象: std::map<std::string, int> disMap() { std::map<std::string, int> tempMap{ {"C语言教程",10},{"STL教程",20} }; return tempMap; } std::map<std::string, int> newMap(disMap()); 在这个示例,disMap()函数创建了一个临时的std::map对象,并初始化了其的一些键值对。然后,使用移动构造函数将这个临时对象移动到了一个新的std::map对象newMap。最终,我们可以通过newMap对象来访问和操作这些键值对。 综上所述,STLC++的标准模板库,提供了一系列的模板类和函数,用于支持通用的数据结构和算法。STL的使用可以提高代码的开发效率和质量,并且通过各种容器和算法,可以方便地处理各种数据结构和算法的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++ STL详解超全总结(快速入门STL)](https://blog.csdn.net/qq_50285142/article/details/114026148)[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++实验】阅读STL源码并分析](https://blog.csdn.net/qq_35760825/article/details/125311509)[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、付费专栏及课程。

余额充值