C++初阶 —— list类

2023-05-16

目录

一,list介绍

二,list的使用

构造函数

list iterator的使用

list capacity

list element access

list modifiers

list迭代器失效

三,list模拟失效


一,list介绍

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

二,list的使用

构造函数

  • list(),构造空list;
  • list(size_type n, const value_type& val=value_type()),构造n个元素值为val的list;
  • list(const list& x),拷贝构造;
  • list(InputIterator first, IputIterator last),用区间中的元素构造list;
int main()
{
	list<int> L1; //空list
	list<int> L2(5, 2); //5个值为2的list
	list<int> L3(L2); //拷贝L2

	string s("abcd");
	list<int> L4(s.begin(), s.end()); //使用迭代器区间构建
    return 0;
}

list iterator的使用

  • begin+end,返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器;
  • rbegin+rend,返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的reverse_iterator,即begin位置;
int main()
{
	string s("abcd");
	list<int> L(s.begin(), s.end()); 

	list<int>::iterator it = L.begin();
	while(it != L.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	list<int>::reverse_iterator rit = L.rbegin();
	while (rit != L.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	return 0;
}

list capacity

  • empty,检测list是否为空;
  • size,返回有效节点个数;
int main()
{
	string s("abcd");
	list<int> L(s.begin(), s.end());
	cout << L.size() << endl;
	cout << L.empty() << endl;
	return 0;
}

list element access

  • front
  • back
int main()
{
	string s("abcd");
	list<char> L(s.begin(), s.end());
	cout << L.front() << endl;
	cout << L.back() << endl;
	return 0;
}

list modifiers

  • push_front,头插;
  • pop_front,头删;
  • push_back,尾插;
  • pop_back,尾删;
  • insert,pos位置插入;
  • erase,pos位置删除;
  • swap,交换;
  • clear,清空有效元素;
int main()
{
	list<int>L, L1;
	L.push_back(2);
	L.push_back(3);
	L.push_front(1);
	L.insert(L.begin(), 0);
	L.erase(--L.end());
	L.pop_back();
	L.pop_front();
	
	L1.push_back(10);
	L.swap(L1);

	L.clear();
	return 0;
}

list迭代器失效

  • 迭代器失效即迭代器所指向的节点无效,即该节点被删除了;
  • list插入不会导致list失效,删除时会失效,其他操作迭代器不受影响;
int main()
{
	list<int> L;
	L.push_back(1);
	L.push_back(2);
	L.push_back(3);
	L.push_back(4);

	auto pos = ++L.begin();
	L.erase(pos);

	//pos位置节点已删除释放,即失效,不可在操作
	++pos;
	*pos;
	return 0;
}

三,list模拟实现

namespace mylist
{
	//节点类模板
	template<class T>
	struct __list_node
	{
		__list_node(const T& data = T())
			:_prev(nullptr)
			, _next(nullptr)
			, _data(data)
		{}

		__list_node<T>* _prev;
		__list_node<T>* _next;
		T _data;
	};

	//迭代器类模板,模仿指针
	//template<class T>
	//struct __list_iterator
	//{
	//	typedef __list_iterator<T> self;
	//	typedef __list_node<T> Node;
	//	Node* _node;
	//
	//	__list_iterator(Node* node)
	//		:_node(node)
	//	{}
	//
	//	//拷贝构造、赋值重载,默认浅拷贝即可
	//	//析构函数,指针指向的节点不属于迭代器的,无需自己销毁
	//
	//	//解引用,*it = it.operator*()
	//	T& operator* ()
	//	{
	//		return _node->_data;
	//	}
	//	//前置++
	//	__list_iterator<T>& operator++()
	//	{
	//		_node = _node->_next;
	//		return *this;
	//	}
	//	//后置++
	//	__list_iterator<T> operator++(int)
	//	{
	//		self tmp = *this;
	//		_node = _node->_next;
	//		return tmp;
	//	}
	//	//前置--
	//	__list_iterator<T>& operator--()
	//	{
	//		_node = _node->_prev;
	//		return *this;
	//	}
	//	//后置--
	//	__list_iterator<T> operator--(int)
	//	{
	//		self tmp = *this;
	//		_node = _node->_prev;
	//		return *this;
	//	}
	//
	//	//比较
	//	bool operator != (const __list_iterator<T>& it) const
	//	{
	//		return _node != it._node;
	//	}
	//	bool operator == (const __list_iterator<T>& it) const
	//	{
	//		return _node == it._node;
	//	}
	//};

	template<class T, class Ref, class ptr>
	struct __list_iterator
	{
		typedef __list_iterator<T, Ref, ptr> self;
		typedef __list_node<T> Node;
		Node* _node;
		 
		__list_iterator(Node* node)
			:_node(node)
		{}

		//拷贝构造、赋值重载,默认浅拷贝即可
		//析构函数,指针指向的节点不属于迭代器的,无需自己销毁

		//解引用,*it = it.operator*()
		Ref& operator* ()
		{
			return _node->_data;
		}
		ptr operator-> () //本来调用为it->->_vale,编译器通过处理省略了一个->
		{
			return &(_node->_data);
		}
		//前置++
		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}
		//后置++
		self operator++(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 *this;
		}

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

	//list类模板
	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_iterator; //typedef const __list_iterator<T> const_iterator; //调用的是迭代器的const函数
		
		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); }
			
	public:
		list()
		{
			_head = new Node;
			_head->_prev = _head;
			_head->_next = _head;
		}
		list(const list<T>& L)
		{
			_head = new Node;
			_head->_prev = _head;
			_head->_next = _head;

			for (const auto& i : L)
			{
				push_back(i);
			}
		}
		//现代写法,还不如传统写法
		//list(const list<T>& L)
		//{
		//	_head = new Node;
		//	_head->_prev = _head;
		//	_head->_next = _head;

		//	list<T> tmp(L.begin(), L.end());
		//	std::swap(_head, tmp._head);
		//}
		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<T>& operator=(list<T> L)
		{
			std::swap(_head, L._head);
			return *this;
		}

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

		void clear()
		{
			auto it = begin();
			//while (it != end())
			//{
			//	Node* cur = it._node;
			//	++it;
			//	delete cur; 
			//}
			//_head->_prev = _head;
			//_head->_next = _head;

			while (it != end())
			{
				it = erase(it);
			}	
		}

		void push_back(const T& x)
		{
			//Node* trail = _head->_prev;
			//Node* newnode = new Node(x);
			//trail->_next = newnode;
			//_head->_prev = newnode;
			//newnode->_prev = trail;
			//newnode->_next = _head;

			insert(end(), x);
		}
		void push_front(const T& x)
		{
			insert(begin(), x);
		}
		void pop_back()
		{
			erase(--end());
		}
		void pop_front()
		{
			erase(begin());
		}

		iterator insert(iterator pos, const T& x)
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;

			Node* newnode = new Node(x);
			newnode->_prev = prev;
			newnode->_next = cur;

			prev->_next = newnode;
			cur->_prev = newnode;

			//return iterator(newnode); //匿名对象
			return 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;
		}

		size_t size()
		{
			size_t sz = 0;
			iterator it = begin();
			while (it != end())
			{
				++it;
				++sz;
			}
			return sz;
		}

		bool empty()
		{
			return begin() == end();
		}

	private:
		Node* _head;
	};
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++初阶 —— list类 的相关文章

  • 枚举列表中的列表

    我有一个约会 并记录了那天发生的事件 我想枚举显示日历的日期的事件列表 我还需要能够从列表中删除事件 def command add date event calendar if date not in calendar calendar
  • python随机字典键,并访问它[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 import random Cards Spade 2 3 4 5 6 7 8 9 10 Jack Queen King
  • AttributeError:尝试删除字符时,“列表”对象没有属性“替换”

    我试图通过执行以下操作从字符串中删除字符 kickoff tree xpath id page div 1 div main div article div div 1 section 2 p 1 b 1 text kickoff kick
  • 在列表列表中查找形状

    节目说明 该计划的目的 我的程序旨在计算 20X15 大小的平面中形状的位置 我有一个形状列表 其中包含形状类型 其 ID 半径或高度以及其在平面上的预期 X Y 位置 我有一个不同的二元运算列表 仅包含形状类型 其 id 及其与另一个形状
  • Python list.extend() 是保序的吗?

    我想知道扩展函数是否保留两个列表中的顺序 gt gt list 1 2 3 gt gt list extend 4 5 gt gt list 1 2 3 4 5 扩展总是这样工作吗 Yes list extend just extends给
  • Python - ValueError:以 10 为基数的 int() 的文字无效:''

    求助 当我尝试从字符串中提取整数时 我不断收到 ValueError invalidliteral for int with base 10 from string import capwords import sys os import
  • python统计前10名

    使用Python 2 6 我有很大的文本文件 以下是前 3 个条目 但我需要检查超过 50 个用户 html log jeff 1153 3 1 84 625 54 1 2 71 3 2 10 7 58 499 3 5 616 36 241
  • 列表:Count 与 Count() [重复]

    这个问题在这里已经有答案了 给定一个列表 首选哪种方法来确定内部元素的数量 var myList new List
  • 如何将 nlsList 中的系数获取到数据帧中?

    有没有办法只从 nlsList 中提取估计值 样本数据 library nlme dat lt read table text time gluc starch solka 1 6 32 7 51 1 95 2 20 11 25 49 6
  • Java 按日期作为字符串对列表 进行排序

    我有一个类型列表 我想按日期元素对该列表进行排序 我用谷歌搜索 看到了一些具有可比性的解决方案 但是是否有可能在不实现类中接口的情况下做到这一点 我的列表如下所示 列表 id 33 文本 test1 日期 06 02 15 id 81 文本
  • 从 XML 文档生成嵌套列表

    在 python 中工作 我的目标是解析我制作的 XML 文档并创建一个嵌套的列表列表 以便稍后访问它们并解析提要 XML 文档类似于以下代码片段
  • 使用 ocaml List.fold_left 列表中的最后一个元素

    我可以通过以下代码找到列表的最后一个元素 let last xs a list a let rec aux xs prev match xs with gt prev x ys gt aux ys x in match xs with gt
  • 从 Json Python 获取特定字段值

    我有一个 JSON 文件 我想做的是获取这个特定字段 id 问题是当我使用json load input file 它说我的变量data是一个列表 而不是字典 所以我不能做类似的事情 for value in data id print d
  • 如何在 Haskell 中获得列表的中间位置?

    我刚刚开始使用 Haskel 学习函数式编程 我正在慢慢度过Erik Meijer 在 Channel 9 的讲座 http channel9 msdn com shows Going Deep Lecture Series Erik Me
  • Ruby 枚举器链接

    在这个例子中 1 2 3 each with index map i j i j gt 0 2 6 我的理解是 既然each with index枚举器链接到map map表现得像each with index通过在块内传递索引 并返回一个
  • 向 list.extend() 传递不可迭代对象

    我正在创建一个公共方法来允许调用者将值写入设备 例如将其称为 write vals 由于这些值将实时输入 因此我希望通过允许用户输入列表或单个值来简化用户的生活 具体取决于他们需要写入的值的数量 例如 write to device 1 2
  • Python - 在和不在列表中语法错误

    我正在尝试从另一个现有的浮点数列表构建一个新的浮点数列表 通过示例更容易识别第一个列表的预期内容 price list 39 99 74 99 24 99 49 99 预期的后期功能 print new price list gt gt 2
  • 比较通用列表和数组

    为什么 generic list 比 array 慢 通用列表比数组稍慢 但在大多数情况下您不会注意到 主要与稍微复杂的查找有关 据说 List 在幕后 使用数组 但不能保证以与数组相同的方式将节点保留在相邻内存中 然而 我早在 2005
  • python 和回文

    我最近写了一个循环的方法 usr share dict words并使用我的返回回文列表ispalindrome x 方法 这是一些代码 有什么问题吗 它只会停止 10 分钟 然后返回文件中所有单词的列表 def reverse a ret
  • 合并多个列表

    鉴于我有一个列表列表 List

随机推荐

  • 分治策略-归并排序

    问题 xff1a 数组排序 分治策略 归并排序 xff1a 1 是合并这些子问题的解 2 分解原问题 xff0c 递归求解 span class token comment coding utf 8 span span class toke
  • 求股票最大收益问题

    问题 xff1a 求股票最大收益 xff0c 股票每天的价格 xff1a 100 113 110 85 105 102 86 63 81 101 94 106 101 79 94 90 97 买进和卖出都在当天结束后进行 xff0c 在某一
  • Python pip 包的安装和卸载 使用。

    Python pip 包的安装和卸载 使用 xff08 一 xff09 pip 安装 一般 来说 Python 需要什么包 直接 pip install 包 即可 但是 这种方法太慢 因为他通过美国的服务器下载 提高 pip 速度 这里提供
  • jdk1.8安装和环境变量配置

    一 安装JDK 选择安装目录 安装过程中会出现两次 安装提示 第一次是安装 jdk xff0c 第二次是安装 jre 建议两个都安装在同一个java文件夹中的不同文件夹中 xff08 不能都安装在java文件夹的根目录下 xff0c jdk
  • python 读取PDF(tabula和pdfminer和pdfplumber的简单操作)

    一 pdfminer 读取PDF 官方文档 xff1a http www unixuser org euske python pdfminer 这里针对python3 1 模块安装 xff1a pip install i https pyp
  • 一区即将要洗的DVD片子

    101 Dalmatians Animated 2009 SE 101斑点狗 预计2009年发行特别版 12 Monkeys 05 10 2005 COM DOC 12只猴子 预计2005年5月10日发行扩展版 加评论和记录片等 2001
  • UML — 五大关系

    在UML教学视频中 xff0c 关系有四种 xff0c 而课本中有五种 xff0c 其实就是多加了一种 xff0c 那么下面我一并总结出来 1 关联关系 通俗点说就是关联关系就是两个对象他们之间的联系和关系 关联分两种 xff1a xff0
  • rhel6.5救援模式修复系统

    如果系统中很多重要的部分被删除了例如 boot下的所有东西 xff0c 则可以通过救援模式 root 64 dazzle1 桌面 mkdir backup root 64 dazzle1 桌面 cp etc fstab backup fst
  • 利用nvm安装npm失败的解决办法

    最近发现在安装nodejs后 xff0c 想使用npm发现自己的电脑上没有安装npm xff0c 可是网上都说安装了nodejs后会自动安装npm xff0c 找了很久解决办法发现没有合适的解决办法 xff0c 于是自己尝试了很久发现了问题
  • chrome 浏览器的缩略图怎么没有了?就是浏览过网页的缩略图,一点击就能打开网站。

    这个问题 xff0c 突然今天解决了 哈哈 分享 首先新标签页 点击左下角 最常访问的网站 点击 最常访问的网站 紧接着再点击被置顶端的 最常访问的网站 Ok xff0c 大功告成了 烦恼了几天的这个小功能 xff0c 有缩略图还是看着舒服
  • 史上最详细的PID教程——理解PID原理及优化算法

    Matlab动态PID仿真及PID知识梳理 云社区 华为云 huaweicloud com 位置式PID与增量式PID区别浅析 Z小旋 CSDN博客 增量式pid https zhuanlan zhihu com p 38337248 期望
  • ubuntu 20.04搭建samba文件共享服务器,实现基于Linux和Windows的共享文件服务

    ubuntu 20 04搭建samba文件共享服务器 xff0c 实现基于Linux和Windows的共享文件服务 超详细 一 xff0c samba的基本概念二 xff0c samba的安装三 xff0c samba的基本配置创建文件夹更
  • ERROR: Could not find a version that satisfies the requirement torchvision

    打docker时出错 xff0c ERROR Could not find a version that satisfies the requirement torchvision from versions 0 1 6 0 1 7 0 1
  • openstack 常用命令回顾及总结

    1 概述 命令实际执行基于OpenStack Queens版本 xff0c 更高版本亦可 xff0c 长时间未使用openstack有些遗忘 xff0c 整理后方便自己回顾学习 xff0c 仅供各位参考 xff0c 详细命令及参数可以参考o
  • TPMS方案 传感器 infineon篇 (SP35 SP37)

    TPMS方案 xff08 SP35 SP37 xff09 传感器 infineon篇 关于sp37无压力芯片目前已有方案 关于sp35传感器已经稳定出货 xff0c 欢迎咨询 硬件原理图 软件说明 xff1a 协议 调制方式 FSK 频率
  • sudo rosdep init 出现 ERROR: cannot download default sources list from:

    sudo rosdep init 出现 ERROR cannot download default sources list from 针对目前安装ROS出现一下指令的错误 span class token function sudo sp
  • 新装linux主机可以ping通,但是SSH无法登陆

    0 xff0c 新装一台linux主机 xff0c 可是ssh连接不上 xff0c 能ping通 怎么办呢 xff1f 1 xff0c 先查看一下防火墙状态 sudo ufw status 2 xff0c 关闭防火墙 sudo ufw di
  • tcp头以及ip头

    转自http www cnblogs com zzq919101 p 7866550 html 在网上找了很多有关tcp ip头部解析的资料 xff0c 都是类似于下面的结构 抽象出图文是这种结构 xff0c 但是在底层中数据到底是怎么传输
  • C++初阶 —— 入门/概念

    目录 一 xff0c 关键字 xff08 C 43 43 98 xff09 二 xff0c 命名空间 命名空间定义 命名空间使用 三 xff0c C 43 43 输入 输出 四 xff0c 缺省参数 五 xff0c 函数重载 六 xff0c
  • C++初阶 —— list类

    目录 一 xff0c list介绍 二 xff0c list的使用 构造函数 list iterator的使用 list capacity list element access list modifiers list迭代器失效 三 xff