IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> C++学习之STL:list的模拟实现与解析 -> 正文阅读

[数据结构与算法]C++学习之STL:list的模拟实现与解析

一级目录:list的介绍

1.在数据结构中,我们都学过list是一个链表,有很多分类,比如单向链表,双向链表,循环链表等等…,但在STL中,list是一个容器,毋庸置疑,是用来保存链表与数据结构中的list有相似之处,但是在实现的时候会更加的绝妙,让人佩服。
首先,我们先看看文档中对STL中list的介绍:

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

2.list的优缺点:
在底层,list的实现方式是双向循环的链表,所以其优缺点与数据结构中的链表是相似的。
优点:
①:由于是链表的存储,所以在任意位置的删除和插入效率非常高,不需要移动数据。
②:可以进行大量的插入和删除,要多少申请多少,不用担心申请过多的不需要空间。
缺点:
①:不支持随机访问,每次访问都必须从头节点(或者指定节点)开始往后(或者往前)逐个访问,效率比较低。
②:底层节点动态开辟,小节点容易造成内存碎片,空间利用率低,缓存利用率低。
3.迭代器
迭代器:目前看来就跟指针的操作是相同的,但是它不是传统指针,而是相当于一个被封装了的指针,并且其操作都是通过操作运算符进行完成的,并且操作和使用与指针相类似。
但是在使用的时候,会存在迭代器失效的问题:
迭代器失效是在进行删除节点的操作中出现的,因为会存在将该节点删除后,再对该节点的迭代器进行操作,这样会使迭代器失效,例如如下操作:

list<int> L;
iterator it = L.begin();
while(it != L.end())
{
   L.erase(it);
   it++;
}
//这个函数是错误的,因为此时it已经被删除了,此时对it进行操作会出现错误;
//改正如下
while(it != L.end())
{
  L.erase(it++);
}
//在删除前让其指向下一个节点即可。

二级目录:list接口

由于在C++中,对于list的使用已经拥有了完整的代码,所以在实现一些有关链表的操作时,我们不需要再重新编写代码,可以使用关于list的接口去调用底层已经实现好的操作。
有关list的接口如下:
1.list的构造接口:

list()//构造一个空的链表
list (size_type n, const value_type& val = value_type()) //构造一个链表,其中还有n个值是val;
list (const list& x)//拷贝构造;
list (InputIterator first, InputIterator last)//用[first, last)区间中的元素构造list;

2.迭代器的接口:
(为了保证迭代器能像指针一样被使用,所以迭代器的各种使用方法都是经过运算符重载)

iterator begin();
iterator end();

3.list的容量:

bool empty();
int size();

4.list元素的访问:

_Ty& front();
_Ty& back();

5.list函数方法接口:

void push_front(value_type a);
void Pop_front();
void push_back(value_type a);
void Pop_back();
iterator insert(iterator _P, const _Ty& _X = _Ty());
iterator erase(iterator _P);
void clear();
void swap(list<int>& L);

三级目录:list的模拟实现

namespace m_list
{
	template<typename _Ty>
	class list
	{
		public:
		struct _Node
		{
			struct _Node* _Prev;
			struct _Node* _Next;
			_Ty _Value;
		};
	public:
		    typedef _Node* _Nodeptr;
			typedef size_t size_type;
			typedef _Ty*   pointer_type;
			typedef _Ty&   reference_type;
			typedef _Ty    value_type;
			typedef const _Ty* const_pointer_type;
			typedef const _Ty& const_reference_type;
	public:
		list():_Head(_BuyNode()),_Size(0)
		{}
	public:
		void push_back(value_type a)
		{
			/*_Nodeptr s = _BuyNode(_Head, _Head->_Prev);
			s->_Value = a;
			s->_Next->_Prev = s;
			s->_Prev->_Next = s;
			_Size++;*/
			insert(end(),a);
		}
		void push_front(value_type a)
		{
			insert(begin(), a);
		}
		void Pop_back()
		{
			/*_Nodeptr p = (--end())._Ptr;
			p->_Next->_Prev = p->_Prev;
			p-> _Prev->_Next = p->_Next;
			free(p);
			--_Size;
			p = nullptr;*/
			erase(--end());
		}
		void Pop_front()
		{
			/*_Nodeptr p = begin()._Ptr;
			p->_Next->_Prev = p->_Prev;
			p->_Prev->_Next = p->_Next;
			free(p);
			--_Size;
			p = nullptr;*/
			erase(begin());
		}
	public:
		class iterator//迭代器,目前我们可以用其代之指针(其实就是一个被封装了的指针)
		{
			friend class list;
		public:
			iterator()
			{}
			iterator(_Nodeptr P) :_Ptr(P)
			{}
			_Ty operator*()
			{
				return _Ptr->_Value;
			}
			_Ty* operator->()
			{
				return &(_Ptr->_Value);
			}
			iterator& operator++()
			{
				_Ptr = _Ptr->_Next;
				return (*this);
			}
			iterator operator++(int)
			{
				iterator r_Ptr = *this;
				++*this;
				return r_Ptr;
			}
			iterator& operator--()
			{
				_Ptr = _Ptr->_Prev;
				return (*this);
			}
			iterator operator--(int)
			{
				iterator r_Ptr = *this;
				--*this;
				return r_Ptr;
			}
			bool operator==(iterator& X)
			{
				return _Ptr == X._Ptr;
			}
			bool operator!=(iterator& X)
			{
				return !(_Ptr == X._Ptr);
			}
			_Nodeptr _Mynode()const
			{
				return _Ptr;
			}
		private:
			_Nodeptr _Ptr;
		};

	public:
		iterator insert(iterator _P, const _Ty& _X = _Ty())
		{
			_Nodeptr s = _P._Mynode();
			s->_Prev = _BuyNode(s, s->_Prev);
			s = s->_Prev;
			s->_Prev->_Next = s;
			s->_Value = _X;
			++_Size;
			return (iterator(s));
		}
		iterator erase(iterator _P)
		{
			_Nodeptr _S = (_P++)._Mynode();
			_S->_Next->_Prev = _S->_Prev;
			_S->_Prev->_Next = _S->_Next;
			_Size--;
			free(_S);
			_S = nullptr;
			return (iterator(_P));
		}
		iterator erase(iterator _F, iterator _L)
		{
			while (_F != _L)
				erase(_F++);
			return (_F);
		}
	public:
		iterator begin()
		{
			return iterator(_Head->_Next);//如同初始化类函数
		}
		iterator end()
		{
			return iterator(_Head);
		}
	public:
		bool empty()
		{
			return _Size == 0;
		}
		int size()
		{
			return _Size;
		}
	public:
		_Ty& front()
		{
			return _Head->_Next->_Value;
		}
		_Ty& back()
		{
			return _Head->_Prev->_Value;
		}
	public:
		void clear()
		{
			erase(begin(), end());
		}
		void swap(list<int>& L)
		{
			std::swap(_Head, L._Head);
		}
	private:
		_Nodeptr _BuyNode(_Nodeptr _Narg = 0, _Nodeptr _Parg = 0)
		{
			_Nodeptr s = (_Nodeptr)malloc(sizeof(_Node));
			s->_Next = _Narg != 0 ? _Narg : s;
			s->_Prev = _Parg != 0 ? _Parg : s;
			return s;
		}
	private:
		_Nodeptr _Head;
		size_type _Size;
	};
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-16 19:05:28  更:2021-11-16 19:06:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 11:48:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码