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

企业做网站营销企业网站 响应式

企业做网站营销,企业网站 响应式,中国站长之家官网,长沙百度关键词搜索在上一篇学习了list的使用后,在本篇我们将通过模拟实现的方式深入了解list的底层运作原理。 作者的个人gitee:楼田莉子 (riko-lou-tian) - Gitee.com 感兴趣的读者可以看一看 目录 前置准备 结点的定义 链表类的定义 迭代器 普通迭代器 const迭代器 …

        在上一篇学习了list的使用后,在本篇我们将通过模拟实现的方式深入了解list的底层运作原理。

        作者的个人gitee:楼田莉子 (riko-lou-tian) - Gitee.com

        感兴趣的读者可以看一看

目录

前置准备

        结点的定义

        链表类的定义

迭代器 

        普通迭代器

        const迭代器 

        list中关于迭代器的声明 

        误区:

相关函数

        push_back

        insert

        erase

源代码


前置准备

        结点的定义

        我们需要定义一个结点的类(参考之前双向链表那篇博客:数据结构学习之双向循环链表-CSDN博客),因为这个类中的成员我们都想要访问,如果想要方便写的话,可以用struct(struct中默认为公开),并且用命名空间封装

namespace Boogiepop
{template<class T>//当我们不需要也不想要让访问限定符限制的时候//可以用struct来定义类,而不是用classstruct list_node{T _data;			//数据list_node<T>* _next;//指向下一个节点的指针list_node<T>* _prev;//指向前一个节点的指针};
}

        同时因为list模拟实现中使用了模板,所以函数的定义也只能在.h文件中() 

        同时切记,模板只能给对应的类或函数使用,是“一次性”的,想再次使用一样的模板必须重新定义

        链表类的定义

template<class T>
class list
{typedef list_node<T> node;
public://构造函数list(){_head = new node;_head->_next = _head;_head->_prev = _head;}
private:node* _head;		//指向头节点的指针};

迭代器 

        双链表迭代器相关图解:

         迭代器用node*封装无法达到预期行为;用类封装node*重载运算符,就可以控制迭代器的行为。

        迭代器行为模拟的是普通指针访问数组的行为

        普通迭代器

	//迭代器template<class T,class Ref>//当我们不需要也不想要让访问限定符限制的时候//可以用struct来定义类,而不是用class//普通迭代器struct _list_iterator{typedef list_node<T> node;typedef _list_iterator<T, Ref> Self;node* _node;//构造迭代器_list_iterator(node* node) :_node(node){}//解引用不是结点//用引用返回可以修改这个数值T& operator*(){return _node->_data;}不能实现,因为const list_iterator对象才能调用这个重载但是在这种情况下const list_iterator对象不能调用++和--//const T& operator*()const//{//	return _node->_data;//}//迭代器++//前置++Self& operator++(){_node = _node->_next;return *this;}//后置Self& operator++(int){_list_iterator<T,Ref> tmp (*this);//浅拷贝_node = _node->_next;return *this;}//前置--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;}};

        const迭代器 

	//const迭代器template<class T,class Ref>//当我们不需要也不想要让访问限定符限制的时候//可以用struct来定义类,而不是用classstruct _list_const_iterator{typedef list_node<T> node;typedef _list_const_iterator<T, Ref> Self;node* _node;//构造迭代器_list_const_iterator(node* node) :_node(node){}//解引用不是结点//用引用返回可以修改这个数值const Self& operator*(){return _node->_data;}//迭代器++//前置++Self& operator++(){_node = _node->_next;return *this;}//后置Self& operator++(int){Self tmp(*this);//浅拷贝_node = _node->_next;return *this;}//前置--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,Ref> iterator;//const迭代器typedef const _list_iterator<T,Ref> const_iterator;//返回迭代器iterator begin(){return iterator(_head->_next);}//返回迭代器iterator end(){return iterator(_head);}//其余部分在此处省略。。。。。。
}

 测试:

void test1()
{Boogiepop::list<int> list;list.push_back(1);list.push_back(2);list.push_back(3);list.push_back(4);list.push_back(5);Boogiepop::list<int>::iterator it = list.begin();while (it != list.end()){cout << *it << " ";++it;}cout<<endl;
}

        普通迭代器可以修改指向的内容,const迭代器不可以修改指向的内容

        误区:

        1、

        这么写是不对的,这样迭代器本身无法修改,无法进行++和--

typedef const iterator const_iterator;

        string和vector可以这么干是因为const修饰的指向的内容 

        但是list只能重新搞一个类型实现

         2、还有这种情况,写重载能否实现?答案是不能

T& operator*()
{return _node->_data;
}
const T& operator*()const
{return _node->_data;
}

        因为:

T& operator*()
{return _node->_data;
}
//不能实现,因为const list_iterator对象才能调用这个重载
//但是在这种情况下const list_iterator对象不能调用++和--
const T& operator*()const
{return _node->_data;
}

        

相关函数

        push_back

void push_back(const T&x)
{node* new_node = new node(x);//头结点node* tail=_head->_prev;//尾节点tail->_next = new_node;new_node->_prev = tail;new_node->_next = _head;_head->_prev = new_node;
}

        insert

void insert(iterator pos, const T& x)
{node* cur = pos._node;node*new_node = new node(x);node*prev = cur->_prev;//prev  new_node  curprev->_next = new_node;new_node->_next = cur;cur->_prev = new_node;new_node->_prev = prev;
}

        erase

iterator erase(iterator pos)
{node* cur=pos._next;node*prev=cur->_prev;node*next=cur->_next;prev->_next=next;next->_prev=prev;delete cur;return iterator(next);//也可以这么写return next
}

源代码

list.h

#pragma once
#include<iostream>
using namespace std;
namespace Boogiepop
{//节点template<class T>//当我们不需要也不想要让访问限定符限制的时候//可以用struct来定义类,而不是用classstruct list_node{T _data;			//数据list_node<T>* _next;//指向下一个节点的指针list_node<T>* _prev;//指向前一个节点的指针//构造函数list_node(const T& x = T()) :_data(x), _next(nullptr), _prev(nullptr){}};//迭代器template<class T, class Ref>//当我们不需要也不想要让访问限定符限制的时候//可以用struct来定义类,而不是用class//普通迭代器struct _list_iterator{typedef list_node<T> node;typedef _list_iterator<T, Ref> Self;node* _node;//构造迭代器_list_iterator(node* node) :_node(node){}//解引用不是结点//用引用返回可以修改这个数值T& operator*(){return _node->_data;}不能实现,因为const list_iterator对象才能调用这个重载但是在这种情况下const list_iterator对象不能调用++和--//const T& operator*()const//{//	return _node->_data;//}//迭代器++//前置++Self& operator++(){_node = _node->_next;return *this;}//后置Self& operator++(int){_list_iterator<T, Ref> tmp(*this);//浅拷贝_node = _node->_next;return *this;}//前置--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;}};//const迭代器template<class T, class Ref>//当我们不需要也不想要让访问限定符限制的时候//可以用struct来定义类,而不是用class//普通迭代器struct _list_const_iterator{typedef list_node<T> node;typedef _list_const_iterator<T, Ref> Self;node* _node;//构造迭代器_list_const_iterator(node* node) :_node(node){}//解引用不是结点//用引用返回可以修改这个数值const Self& operator*(){return _node->_data;}//迭代器++//前置++Self& operator++(){_node = _node->_next;return *this;}//后置Self& operator++(int){Self tmp(*this);//浅拷贝_node = _node->_next;return *this;}//前置--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;}};//链表template<class T, class Ref>class list{typedef list_node<T> node;typedef _list_iterator<T, Ref> Self;typedef _list_const_iterator<T, Ref> const_Self;public://普通迭代器typedef _list_iterator<T, Ref> iterator;//const迭代器typedef const _list_iterator<T, Ref> const_iterator;//返回迭代器iterator begin(){return iterator(_head->_next);}//返回迭代器iterator end(){return iterator(_head);}//构造函数list(){_head = new node;_head->_next = _head;_head->_prev = _head;}//拷贝构造函数list(const list<T>& lt){_head = new node;_head->_next = _head;_head->_prev = _head;for (const auto& x : lt){push_back(x);}}//花括号初始化list(initializer_list<T> il){_head = new node;_head->_next = _head;_head->_prev = _head;for (const auto& x : lt){push_back(x);}}//=运算符重载list<T>& operator=(const list<T>& lt){if (this != &lt){clear();for (const auto& x : lt){push_back(x);}}return *this;}//析构函数//释放结点~list(){clear();delete _head;_head = nullptr;}void push_back(const T& x){node* new_node = new node(x);//头结点node* tail = _head->_prev;//尾节点tail->_next = new_node;new_node->_prev = tail;new_node->_next = _head;_head->_prev = new_node;}//交换数据void swap(list<T>& lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}//插入元素void insert(iterator pos, const T& x){node* cur = pos._node;node* new_node = new node(x);node* prev = cur->_prev;//prev  new_node  curprev->_next = new_node;new_node->_next = cur;cur->_prev = new_node;new_node->_prev = prev;}void push_back(const T& x){insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void pop_front(){erase(begin());}void pop_back(){erase(--end());}void clear(){iterator it = begin();while (it != end()){it = erase(it);}}iterator erase(iterator pos){node* cur = pos._next;node* prev = cur->_prev;node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;return iterator(next);//也可以这么写return next}//返回链表大小size_t size()const{}private:node* _head;		//指向头节点的指针};
};

       

        提示:类的模板没有实例化不能去类模板中找后面的东西编译器无法区分const_iterator 是嵌套内类还是静态成员变量,typename是告诉编译器确认过是类型

        本期内容就到这里,感兴趣的可以点个赞谢谢

封面图自取: 

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

相关文章:

  • 深度学习C++中的数据结构:栈和队列
  • 2025-tomcat web实践
  • 免费建立微信网站如何设计的英文网站
  • liferay 做网站哪里有网站开发公司
  • Leetcode 38
  • Django 学习路线图
  • 把网站放到服务器公司做网站需要准备什么资料
  • 如何批量获取蛋白质序列的所有结构域(domain)数据-2
  • MySQL基础知识大全
  • 站群服务器都有什么作用
  • C# 初级编程
  • linux fair调度器
  • 建设工程项目在哪个网站查询零食网站页面模板
  • Python 基础详解:enumerate() 函数
  • 基于鸿蒙UniProton的车载信息娱乐系统开发指南
  • 自然语言处理前沿创新方向与技术路径
  • 微软做网页的软件烟台优化网站公司
  • 使用Jmeter进行http接口测试
  • Jenkins从节点配置全攻略:从搭建到任务调度,参数详解与实战指南
  • 【Agentic AI】提示链模式学习笔记
  • 广东省省考备考(第一百三十三天10.25)——科学推理(强化训练)
  • 四季变化,室外太阳光的剧烈变化, 从“被动适应”到“主动免疫”,机器视觉检测如何实现?
  • 观察者模式学习
  • 常用标准电阻表 | E24标准电阻表
  • 三、检索增强生成(RAG)技术体系
  • 【Leetcode hot 100】739.每日温度
  • JAVA国际版任务悬赏发布接单系统源码支持IOS+Android+H5
  • 网站做选择题怎么快速选择艺术品拍卖网站源码php
  • 大模型微调完整步骤( LLama-Factory)
  • Rust + PostgreSQL:deadpool 和 diesel 数据库连接池实战(四)