c++的学习之路:15、list(2)

本章主要是讲模拟实现list,文章末附上代码。

目录

一、创建思路

二、构造函数

 三、迭代器

四、增删

五、代码


一、创建思路

如下方代码,链表是由一块一块不连续的空间组成的,所以这里写了三个模板,一个是节点,一个是迭代器,分别放在struct创建的类,因为这个是可以直接访问,从下方代码可以看出我是在list里面定义了一个head,这个就是哨兵位头节点,然后在list_node里面写的就是节点的初始化,需要使用时直接new一个,_list_iterator这个就是迭代器写的地方了,这里也是直接写了两个一个普通的迭代器,一个const的。

namespace ly
{
    template<class T>
    struct list_node
    {
        list_node<T>* _next;
        list_node<T>* _prev;
        T _data;

        list_node(const T& x = T())
            :_next(nullptr)
            , _prev(nullptr)
            , _data = x
        {}
    };

    template<class T,class Ref,class Ptr>
    struct _list_iterator
    {
        typedef list_node<T> node;
        typedef __list_iterator<T, Ref, Ptr> self;

        node* _node;

        node* _node;

        _list_iterator(node* n)
            :_node(n)
        {}

    };

    template<class T>
    class list
    {
    public:
        typedef list_node<T> node;
        typedef _list_iterator<T, T&, T*> iterator;
        typedef _list_iterator<T, const T&, const T*> const_iterator;
    private:
        node* _head;
    };
}

二、构造函数

如下方代码所示就是我写的构造函数,因为这个链表是一个双向循环带头链表所以,直接new一个node在把哨兵位的next和prev指向自己,就创建出了一个链表,如下方图片可以看出创造出来了。

        list()
        {
            _head = new node;
            _head->_next = _head;
            _head->_prev = _head;
        }

 三、迭代器

这里是把迭代器能用到的都写了,例如解引用,就是利用这个节点指针直接访问就可以了,但是考虑到了可能访问常量指针所以,这里就是利用模板参数进行访问的,第二个就是相当于访问数据了,因为在流输出的时候正常是访问不到,因为迭代器访问的是这个节点的额指针,这时重载了一个->就可以正常访问了,++就是下一个节点的地址,也就是这个节点里面存入的next,前置和后置在之前文章中都说过,这里就不详细介绍了,后置就是价格int以作区分,--也是类似操作,==与!=直接判断节点的地址是否相同就可以了。

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

        Ptr operator->()
        {
            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 tmp;
        }

        bool operator==(const self& s)
        {
            return _node == s._node;
        }

        bool operator!=(const self& s)
        {
            return _node != s._node;
        }

四、增删

再写数据结构的顺序表的时候就知道了,头插尾插头删尾删是可以直接使用inster的,所以这里是直接写了inster在进行调用的,代码如下,测试代码如下,结果如图,这里是直接调用insert的所以就不测试这个了。

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

        void push_back(const T& x)
        {
            insert(end(),x);
        }

        void push_front(const T& x)
        {
            insert(begin(), x);
        }

        void pop_back()
        {
            erase(--end());
        }

        void pop_front()
        {
            erase(begin());
        }

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

        void erase(iterator pos)
        {
            assert(pos != end());
            node* prev = pos._node->_prev;
            node* next = pos._node->_next;
            prev->_next = next;
            next->_prev = prev;
            delete pos._node;
        }

void Test1()
    {
        list<int> l1;
        l1.push_back(1);
        l1.push_back(2);
        l1.push_back(3);
        l1.push_back(4);
        print(l1);
        l1.push_front(5);
        l1.push_front(6);
        l1.push_front(7);
        l1.push_front(8);
        print(l1);
        l1.pop_back();
        l1.pop_back();
        print(l1);
        l1.pop_front();
        l1.pop_front();
        print(l1);
    }

           

五、代码

#pragma once
#include <assert.h>
namespace ly
{template<class T>struct list_node{list_node<T>* _next;list_node<T>* _prev;T _data;list_node(const T& x = T()):_next(nullptr), _prev(nullptr), _data(x){}};template<class T, class Ref, class Ptr>struct _list_iterator{typedef list_node<T> node;typedef _list_iterator<T, Ref, Ptr> self;node* _node;_list_iterator(node* n):_node(n){}Ref operator*(){return _node->_data;}Ptr operator->(){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 tmp;}bool operator==(const self& s){return _node == s._node;}bool operator!=(const self& s){return _node != s._node;}};template<class T>class list{public:typedef list_node<T> node;typedef _list_iterator<T, T&, T*> iterator;typedef _list_iterator<T, const T&, const T*> const_iterator;list(){_head = new node;_head->_next = _head;_head->_prev = _head;}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);}void push_back(const T& x){insert(end(),x);}void push_front(const T& x){insert(begin(), x);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}void insert(iterator pos,const T& x){node* cur = pos._node;node* prev = cur->_prev;node* new_node = new node(x);prev->_next = new_node;new_node->_prev = prev;new_node->_next = cur;cur->_prev = new_node;}void erase(iterator pos){assert(pos != end());node* prev = pos._node->_prev;node* next = pos._node->_next;prev->_next = next;next->_prev = prev;delete pos._node;}private:node* _head;};void print(list<int> l){list<int>::iterator it = l.begin();while (it != l.end()){cout << *it << ' ';it++;}cout << endl;}void Test1(){list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);print(l1);l1.push_front(5);l1.push_front(6);l1.push_front(7);l1.push_front(8);print(l1);l1.pop_back();l1.pop_back();print(l1);l1.pop_front();l1.pop_front();print(l1);}
}#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>using namespace std;#include "list.h"int main()
{ly::Test1();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/797734.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯第六届c++大学B组详解

前言&#xff1a; 看了很多博客以及视频讲解&#xff0c;感觉都不是很清楚&#xff0c;比较模棱两可&#xff0c;所以干脆自己一边想&#xff0c;一边写博客&#xff0c;也可帮助到其他人&#xff0c;都是根据自己的逻辑来尽量清楚简单的讲清楚题目&#xff0c;喜欢的不要吝啬三…

HTTP的介绍

一.什么是HTTP&#xff1f; Hyper Text Transfer Protocol,超文本传输协议&#xff0c;规定了浏览器和服务器之间数据传输的规则。 二.HTTP的特点 &#xff08;1&#xff09;基于TCP协议&#xff1a;面向连接&#xff0c;安全 &#xff08;2&#xff09;基于请求-响应模型的&…

卡奥斯工业互联网平台分析

一、 背景 卡奥斯是海尔推出的具有中国自主知识产权、全球首家引入用户全流程参与体验的工业互联网平台。其核心是大规模定制模式&#xff0c;通过持续与用户交互&#xff0c;将硬件体验变为场景体验&#xff0c;将用户由被动的购买者变为参与者、创造者&#xff0c;将企业由原…

【1】初识 Python

【1】初识 Python 1、编程语言(1) 语言(2) 编程语言(3) 如何利用编程语言与计算机交流(4) 常见的编程语言(5) 语法 2、Python 简介(1) 什么是 Python(2) Python 能做什么(3) Python 的由来(4) Python的特点① 语法精简② 生态好&#xff0c;开发效率高③ Python开发初体验&…

练习 21 Web [GXYCTF2019]BabySQli

SQL联合查询&#xff0c;注意有源码看源码&#xff0c;Base64以及32的区别&#xff0c;MD5碰撞 打开后有登录框&#xff0c;先随意登录尝试 只有输入admin才是返回wrong pass&#xff01; 其他返回wrong user 所以用户名字段一定要输入admin 养成好习惯&#xff0c;先查看源码…

删除mysql表卡死 , 打不开,一直转圈圈

最近用navicat删除某一张表时&#xff0c;直接卡死转圈圈&#xff0c;导致navicat直接无响应, 想着是不是自己navicat有问题&#xff0c;换同事电脑来删这张表&#xff0c;还是同样问题。 多次尝试才整明白&#xff0c;根本不是navicat的问题.是mysql 的表锁死了! 如果频繁的对…

华三Sec Path

1、设备特点 外观&#xff1a; 功能特点&#xff1a; 安全特性&#xff1a; vFW的默认账号密码&#xff1a;admin 2、安全区域 1&#xff09;相同安全级别的集合 2&#xff09;默认的安全域 【1】区域 trust、untrust、local&#xff08;所有有接口属于local&#xff0c;…

机器人开启私聊配置自定义接口的方式

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。 今天给大家介绍一下&#xff0c;如何在机器人中开启私聊回复。 前提条件&#xff1a;机器人已经启动好了&#xff0c;且功能也都可以正常使用&#xff0c;如果没有启动&#xff0c;可以联…

一网打尽计算机网络难题:100个问答助你轻松掌握【文末送书福利】

文章目录 一&#xff0c;物理层二&#xff0c;数据链路层三&#xff0c;网络层四&#xff0c;传输层五&#xff0c;应用层专栏推荐粉丝福利 欢迎订阅查看学习&#xff1a;Java编程基础教程系列&#xff08;零基础小白搬砖逆袭&#xff09; 一&#xff0c;物理层 题&#xff1a…

【攻防世界】unseping (反序列化与Linux bash shell)

打开题目环境&#xff1a; 1、进行PHP代码审计&#xff0c;通过审计得知需要用到PHP反序列化。找到输出flag的位置为 ping()函数。通过使用 exec() 函数来执行 $ip 并将结果保存在 $result 中&#xff0c;最终输出 $result。 2、接着寻找给 $ip 传参的位置&#xff0c;发现通过…

VMware Esxi安装群辉系统

群晖的网络存储产品具有强大的操作系统&#xff0c;提供了各种应用程序和服务&#xff0c;包括文件共享、数据备份、多媒体管理、远程访问等。用户可以通过简单直观的界面来管理他们的存储设备&#xff0c;并且可以根据自己的需求扩展设备的功能。总的来说&#xff0c;群晖的产…

配置vscode用于STM32编译,Debug

配置环境参考&#xff1a; Docs 用cubemx配置工程文件&#xff0c;用VScode打开工程文件。 编译的时候会有如下报错&#xff1a; vscode出现process_begin :CreateProcess failed 系统找不到指定文件 解决方案&#xff1a;在你的makefile中加上SHELLcmd.exe就可以了 参考…

云his系统源码 java源码saas模式 二甲医院his系统全套源码 数据库MySQL + MyCat

基层医院云HIS系统源码 一款满足基层医院各类业务需要的云HIS系统。该系统能帮助基层医院完成日常各类业务&#xff0c;提供病患挂号支持、病患问诊、电子病历、开药发药、会员管理、统计查询、医生站和护士站等一系列常规功能&#xff0c;还能与公卫、PACS等各类外部系统融合&…

JavaWeb--JavaScript Part 01

1. JavaScript概述 JavaScript&#xff08;简称JS&#xff09;是一种轻量级的、解释执行的客户端脚本语言&#xff0c;主要用于增强网页的交互性和动态性。它起源于Netscape的LiveScript&#xff0c;并在1995年发布时更名为JavaScript。尽管名称中包含"Java"&#xf…

leetcode.707. 设计链表

题目 题意&#xff1a; 在链表类中实现这些功能&#xff1a; get(index)&#xff1a;获取链表中第 index 个节点的值。如果索引无效&#xff0c;则返回-1。 addAtHead(val)&#xff1a;在链表的第一个元素之前添加一个值为 val 的节点。插入后&#xff0c;新节点将成为链表的…

CDN撞上云防护:技术视角下的差异与协同作用

引言 随着互联网业务全球化和服务需求的不断增长&#xff0c;内容分发网络&#xff08;CDN&#xff09;和云防护已成为现代企业保障网站性能、安全性和可靠性的关键工具。尽管两者在提升用户体验及确保服务连续性方面都有显著作用&#xff0c;但它们各自的核心技术和应用场景有…

2024年选择云渲染平台必须注意这5点!看完你就懂了

云渲染平台这么多&#xff0c;你是不是正在为选择哪一家而困惑&#xff1f; 随着云渲染技术的进一步发展&#xff0c;市面上的云渲染平台也越来越多&#xff0c;其中鱼龙混杂的也不在少数。对于设计师和设计公司来说&#xff0c;如何选择一个可靠且适合自己的云渲染平台成为一…

Godot 4 教程《勇者传说》依赖注入 学习笔记(0):环境配置

文章目录 前言相关地址环境配置初始化环境配置文件夹结构代码结构代码运行 资源文件导入像素风格窗口环境设置背景设置,Tileap使用自动TileMap 人物场景动画节点添加站立节点添加移动动画添加 通过依赖注入获取Godot的全局属性项目声明 当前项目逻辑讲解角色下降添加代码位置问…

CTF之GET和POST

学过php都知道就一个简单传参&#xff0c;构造payload:?whatflag得到 flag{3121064b1e9e27280f9f709144222429} 下面是POST那题 使用firefox浏览器的插件Hackbar勾选POST传入whatflag flag{828a91acc006990d74b0cb0c2f62b8d8}

论文阅读AI工具链

文献检索 可以利用智谱清言来生成合适的文献检索式&#xff0c;并根据需要不断调整。 谷歌学术 在Google Scholar中进行检索时&#xff0c;您可以使用类似的逻辑来构建您的搜索式&#xff0c;但是语法会有所不同。Google Scholar的搜索框接受普通的文本搜索&#xff0c;但是…