【1++的C++初阶】之list

这篇具有很好参考价值的文章主要介绍了【1++的C++初阶】之list。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

👍作者主页:进击的1++
🤩 专栏链接:【1++的C++初阶】

一,什么是list

list是可以在常数范围内进行任意插入和删除的序列式容器。
list底层是前后循环链表,因此可以双向前后迭代。与其他序列式容器相比,list的最大缺陷是不支持任意位置的随机访问。并且list还需要一些额外的空间来保存结点与结点间的相关联信息。

二,构造与析构

2.1 结点结构

template<class T>
	struct list_node
	{
		list_node* prev;//指向上一个结点
		list_node* next;//指向下一个结点
		T data;
		//构造
		list_node(const T& val = T())
			:data(val)
			, prev(nullptr)
			, next(nullptr)
		{}
	};

在此结构中,定义出来了指向结点的前后指针,结点数据类型并对上述成员变量进行了初始化。

2.2 链表结构

template<class T>
	class list
	{
	public:
		typedef list_node<T> Node;
		//构造
		list()
		{
			_head = new Node;
			_head->prev = _head;
			_head->next = _head;
		}

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

//拷贝构造

template <class InputIterator>
		list(InputIterator first, InputIterator last)
		{
			_head = new Node;
			_head->prev = _head;
			_head->next = _head;
			while (first != last)
			{
				push_back(*first);
				first++;
			}
		}

		//拷贝构造
		//现代写法
		list(const list<T>& lt)
		{
			_head = new Node;
			_head->prev = _head;
			_head->next = _head;
			list<T> tmp(lt.begin(), lt.end());
			std::swap(_head, tmp._head);
		}

       ~list()
		{
			clear();
			delete _head;
			_head = nullptr;
		}
	private:
		Node* _head;	
	};

此结构中定义了头结点,并对头结点进行了初始化,使其指向上一个的指针指向自己,指向下一个的指针指向自己。
拷贝构造我们用的是现代写法,通过迭代器构造,构造出一个临时对象,再将其头结点指针进行交换。需要注意的是:在拷贝前都要进行初始化,防止其成为野指针。
在析构之前先将哨兵位头结点前的结点进行释放,因此就有了clear()函数,最后在析构时就只需将头结点释放。

2.3 迭代器结构

template<class T, class Ref, class Ptr>
	struct list_iterator
	{
		typedef list_iterator<T,Ref,Ptr> iterator;
		typedef list_node<T> Node;
		//申请一个结点指针
		Node* _node;
		//构造
		list_iterator(Node* node)
			:_node(node)
		{}
	};

list迭代器的本质就是一个指向结点的指针。先是申请结点指针,进行初始化,使其指向传过来的结点指针。

三,部分重要接口的作用及其实现

3.1 迭代器相关的接口

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

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

		Ref operator *()
		{
			return _node->data;
		}

		Ptr operator->()
		{
			return &(operator*());
		}

		iterator& operator++()
		{
			_node = _node->next;
			return *this;
		}

		iterator operator++(int)
		{
			iterator tmp = *this;
			_node = _node->next;
			return tmp;
		}

		iterator& operator--()
		{
			_node = _node->prev;
			return *this;
		}

		iterator operator--(int)
		{
			iterator tmp = *this;
			_node = _node->prev;
			return tmp;
		}

因为list迭代器是自定义类型,因此迭代器之间的一些操作,我们就必须要进行函数重载。我们解释几个比较重要的函数重载 。

   Ptr operator->()
		{
			return &(operator*());
		}

此重载所适合的环境:当list中存储的也是一个结构体是,此运算符就能够使用。
例:


  struct pos
  {
    int a;
    int b;
  };
  list<pos> lt;
  list<pos>::iterator it=lt.begin();
  it->a;

在此函数内部,返回了&(operator*()),而operator*()我们也进行了重载,返回的是结点数据–data,要是按此形式,那么此函数最终返回的就是data的地址。这与我们上述it->a不符合。原因在于,此处还有个隐藏的->,其最终形式为:it->data->a;这是编译器为了语法的可读性,而进行的的特殊处理。
【1++的C++初阶】之list,1++的C++初阶,c++,list,stl

说完->重载,我们在来说说++的重载。

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

由于list的空间是不连续的,因此迭代器++,就是到下一结点。

3.2 list相关接口

inert的实现

iterator insert(iterator pos,const T& val)
		{
			Node* cur = pos._node;
			Node* newnode = new Node(val);
			Node* prev = cur->prev;
			prev->next = newnode;
			newnode->prev = prev;
			newnode->next = cur;
			cur->prev = newnode;
			return iterator(newnode);

		}

【1++的C++初阶】之list,1++的C++初阶,c++,list,stl
【1++的C++初阶】之list,1++的C++初阶,c++,list,stl
erase的实现

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);
		}

【1++的C++初阶】之list,1++的C++初阶,c++,list,stl
【1++的C++初阶】之list,1++的C++初阶,c++,list,stl
【1++的C++初阶】之list,1++的C++初阶,c++,list,stl文章来源地址https://www.toymoban.com/news/detail-601943.html

到了这里,关于【1++的C++初阶】之list的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++初阶】STL之学习string的用法

    STL是C++的标准模板库 ,里面包含了许多 算法和数据结构 ,例如我们熟悉的顺序表、链表、栈和队列以及一些常见的算法等等,编程者想使用这些就可以直接从库中调用,不必再自己造轮子了。 下面为STL内容的一张图: 接下来,我们要学习STL中的string。 string 是C++的一个类模

    2024年02月04日
    浏览(32)
  • 【C++初阶】STL详解(四)vector的模拟实现

    本专栏内容为:C++学习专栏,分为初阶和进阶两部分。 通过本专栏的深入学习,你可以了解并掌握C++。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:C++ 🚚代码仓库:小小unicorn的代码仓库🚚 🌹🌹🌹关注我带你学习编程知识 注:为了防止与标准库当中的vector产生命名冲突

    2024年02月05日
    浏览(33)
  • 【C++初阶】STL详解(二)string类的模拟实现

    本专栏内容为:C++学习专栏,分为初阶和进阶两部分。 通过本专栏的深入学习,你可以了解并掌握C++。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:C++ 🚚代码仓库:小小unicorn的代码仓库🚚 🌹🌹🌹关注我带你学习编程知识 注:为了防止与标准库当中的string类产生命名冲

    2024年02月05日
    浏览(39)
  • 【C++初阶】九、STL容器中的string类(上)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【C++初阶】八、初识模板(泛型编程、函数模板、类模板)-CSDN博客  ==============================

    2024年02月04日
    浏览(41)
  • C++初阶(十四)list

    📘北尘_ :个人主页 🌎个人专栏 :《Linux操作系统》《经典算法试题 》《C++》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。 list的底层是双向链表结构,双向链表中每个

    2024年02月04日
    浏览(25)
  • C++初阶(十一) list

    list的文档介绍 1. list是可以在常数范围内在 任意位置进行插入和删除 的序列式容器,并且该容器 可以前后双向迭代。 2. list的 底层是双向链表结构 ,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向 其前一个元素和后一个元素。 3. list与forward_lis

    2024年02月20日
    浏览(30)
  • 【C++】STL---list

    list 是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。 list 的底层是 双向链表 结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。 list 与 forward_list 非常相似:最主要的不

    2024年02月11日
    浏览(29)
  • C++:STL--List

    STL容器的代码设计中, 模板编程 和 代码复用的思想贯穿始终 ,代码复用可以将各个成员接口统一起来从而 大大增加程序的可读性和可维护性 ,模板编程使得容器类可以 根据需要用于存储各种不同类型的数据 . C++STL标准库中的list使用的数据结构是带头双向循环链表 ; 链表的头

    2024年02月10日
    浏览(29)
  • C++ STL list

    ✅1主页:我的代码爱吃辣 📃2知识讲解:C++之 STL list介绍和模拟实现 ☂️3开发环境:Visual Studio 2022 💬4前言:上次我们详细的介绍了vector,今天我们继续来介绍一下TSTL中的另外一个容器list。list在基础的功能和结构上就是一个双向带头的循环链表,实现起来基本不难,但是

    2024年02月13日
    浏览(26)
  • 【C++初阶】C++STL详解(三)—— vector的介绍及使用

    ​ ​📝个人主页:@Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:C++学习 🎯 长路漫漫浩浩,万事皆有期待 上一篇博客:【C++】string类常见题目详解(二) —— 把字符串转换成整数、反转字符串、反转字符串 II、反转字符串中的单词 III、字符

    2024年02月11日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包