当前位置: 首页 > news >正文

std之list

目录

前言:

一.list的介绍

二.list的模拟实现以及实现中所需要的细节

1.实现每个元素的类

2.主类

3.构造函数

4.push_back

5.迭代器函数以及迭代器类的实现

6.insert和erase

7.拷贝构造和operator=

结言:


前言:

我们今天讲一下list的内置函数以及list的模拟实现。在数据结构中我们学习了链表,之后我们还会根据我们所学的内容来实现stack和queue和priority_queue不过那都是后话了。今天我来给大家完整的讲一下list的内置函数以及一些常用的内置函数的实现。

一.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的模拟实现以及实现中所需要的细节

在简单介绍完之后list的大致内容后我们先来实现一下我们自己list的一个基本框架。list主要有3部分组成。一个是list每一个元素中的详细内容,还有一个就是存储链表的。以及一个迭代器的设置。

1.实现每个元素的类

template<class T>struct ListNode {T _date;ListNode<int>* _prev;ListNode<int>* _next;ListNode(const T node):_date(node),_prev(nullptr), _next ( nullptr){; }};

有人可能会好奇为什么我们使用struct而不是class呢?在我们的基础语法中我们提到了struct和class的区别。他们两个都能进行对类的定义,而有不同的是struct的基本类型是public而class的基本类型是private。所以这边我们可以用struct定义或者是在class中进行public。

这个类里面我们分别定义了_data,_prev_next我们用这三个变量实现对数据的存储。

2.主类

第二个类主要的就是实现我们对我们list的控制,基本上所有的操作都是在list中进行。

	template<class T>class list{public:typedef ListNode<T> Node;private:Node* _ahead;};

在没有实现迭代器之前我们主要进行的工作就只有这些了。

3.构造函数

		void empty_init(){_head = new Node(T());_head->_next = _head;_head->_prev = _head;}List(){empty_init();}

将这两部分分离的目的主要是empty_init函数后面会多次进行使用。

4.push_back

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

基本操作与我们在数据结构上学的链表几乎相同。

5.迭代器函数以及迭代器类的实现

template<class T,class Tqu,class Con>class ListIterator {typedef ListIterator<T, Tqu,Con> self;typedef ListNode<T> Node;public:Node* _node;ListIterator(Node* node):_node (node){}self& operator ++(){_node = _node->_next;return *this;}self& operator --(){_node = _node->prev;return *this;}self& operator ++(int){self tmp = _node;_node = _node->_next;return tmp;}bool operator!=(const self& it){return _node != it._node;}bool operator==(const self& it){return _node == it._node;}Tqu operator*(){return _node->_date;}};

在list中由于不是一块连续的空间导致我们不可以使用[]去访问,所以我们就不可以把迭代器单纯的看作是一个指针了。那么问题又来了那么我们要怎么去实现指针才能实现的内容呢?这时就需要用到我们的operator了。如上述代码所展示。

模板后面两个参数是T*和T&主要的作用是在增加const变量时不需要手动再写一个函数。

        typedef ListIterator<T, T&, T*> iterator;typedef ListIterator<T, const T&,const T*> const_iterator;
iterator begin(){iterator tmp(_head->_next);return tmp;}iterator end(){iterator tmp(_head);return tmp;}const_iterator begin() const{iterator tmp(_head->_next);return tmp;}const_iterator end(){iterator tmp(_head);return tmp;}

这些就是我们迭代器所需要的内置类型函数了。

6.insert和erase

iterator insert(iterator pos,const T&x){Node* newnode = new Node(x);Node* cur = pos._node;Node* prev = pos._node->_prev;//prev newnode curnewnode->_next = cur;newnode->_prev = prev;prev->_next = newnode;cur->_prev = newnode;return iterator(newnode);}iterator erase(iterator pos){assert(pos != end());Node* cur = pos._node;Node* prev = pos._node->_prev;Node* next = cur->_next;//prev cur nextprev->_next = next;next->_prev = prev;delete cur;cur = nullptr;return iterator(next);}

这两个函数的作用主要是在指定位置插入数据,以及在指定位置删除数据。

7.拷贝构造和operator=

		List(List<T>& lt){empty_init();for (auto& e : lt){push_back(e);}}list<T>& operator=(list<T> lt){swap(_head, lt._head);return *this;}

基本上也是很简单,需要注意的时候我们在进行拷贝构造的时候需要定义一个新的开年表所以我们需要对它进行初始化。

结言:

list与vetcor的实现思路基本上相似的。不过他们在内存上有着本质上的区别。他们两个各有各的好处。好了今天的内容就到此为止了。

http://www.dtcms.com/a/585884.html

相关文章:

  • 前端:前端/浏览器 可以录屏吗 / 实践 / 录制 Microsoft Edge 标签页、应用窗口、整个屏幕
  • 做网站像美团一样多少钱中国最新军事消息
  • 软件项目管理实验报告(黑龙江大学)
  • 网络建设需求台州做网站优化
  • PostgreSQL一些概念特性
  • 宁夏建设厅网站6青岛网站建设公司好找吗
  • 社交营销可以用于网站制作行业吗怎样做建网站做淘客
  • 玩转Rust高级应用 如何让让运算符支持自定义类型,通过运算符重载的方式是针对自定义类型吗?
  • 基于Keras的MNIST手写数字识别卷积神经网络设计与实现
  • 百度资料怎么做网站型云网站建设
  • IP配置的基本要求
  • 单母线接线典型操作顺序
  • LightGBM三部曲:LightGBM原理
  • 【C++】C++中的文件IO
  • wordpress手机站如何做负面口碑营销案例
  • 谷歌黑客语法挖掘 SQL 注入漏洞
  • ps做网站logo青海做网站多少钱
  • Qt开发——环境搭建
  • 32HAL——RTC时钟
  • C#知识补充(一)——ref和out、成员属性、万物之父和装箱拆箱、抽象类和抽象方法、接口
  • 专业的设计网站建设网站做地区定位跳转
  • 网站做三层结构南京建设网站哪家好
  • pyautocad 获取选择线段的近似最小包围盒 (OBB) 三分搜索
  • Git Commit 高频提示详解:用户名邮箱配置及其他常见提示解决方案
  • 打开网站图片弹入指定位置代码网络域名备案查询
  • 豆包 Spring 常用注解详解及分类
  • 企业网站建设收费最大的网站开发公司
  • 服务器运维(六)跨域配置 Preflight 问题——东方仙化神期
  • 第三次作业-第四章网站搭建
  • React 17