算法刷题笔记 双链表(C++实现)

文章目录

    • 题目描述
    • 基本思路
    • 实现代码

题目描述

  • 实现一个双链表,双链表初始为空,支持5种操作:

    • 在最左侧插入一个数;
    • 在最右侧插入一个数;
    • 将第k个插入的数删除;
    • 在第k个插入的数左侧插入一个数;
    • 在第k个插入的数右侧插入一个数
  • 现在要对该链表进行M次操作,进行完所有操作后,从左到右输出整个链表。

  • 注意:题目中第k个插入的数并不是指当前链表的第k个数。例如操作过程中一共插入了n个数,则按照插入的时间顺序,这n个数依次为:第1个插入的数,第2个插入的数,…第n个插入的数。

输入格式

  • 第一行包含整数M,表示操作次数。
  • 接下来M行,每行包含一个操作命令,操作命令可能为以下几种:
    • L x,表示在链表的最左端插入数x
    • R x,表示在链表的最右端插入数x
    • D k,表示将第k个插入的数删除。
    • IL k x,表示在第k个插入的数左侧插入一个数。
    • IR k x,表示在第k个插入的数右侧插入一个数。

输出格式

  • 共一行,将整个链表从左到右输出。

数据范围

  • 1 ≤ M ≤ 100000
  • 所有操作保证合法。

基本思路

  • 双链表实际上就是对单链表的衍生。单链表中,每一个结点只需要存储自己的下一个结点的位置(通过下标或指针的方式)即可,但是双链表中的结点需要存储自己的上一个结点的位置。另外,双链表中往往不只有头指针,还有尾指针。
  • 和单链表的实现思路类似,出于效率考虑,我们并不会在每次新建一个链表结点时都使用C++中的new运算符创建一个新结点,而是开辟一个空间足够大的静态数组,来模拟单链表。链表中每一个结点存储的左右两个结点的位置也分别通过一个静态数组进行表示。本题的最大难点就是对于每一种操作,都需要考虑是否要分情况,是否要合并多种情况。

实现代码

#include <iostream>
using namespace std;

const int N = 1e5 + 10;
int list[N];
int l[N], r[N];
int head = -1, tail = -1, current = 0;

inline void insert_left(void)
{
    // 输入结点信息
    int x;
    cin >> x;
    // 创建一个新结点
    list[current] = x;
    l[current] = -1;
    r[current] = head;
    // 修改原先的首结点
    if(head != -1) l[head] = current;
    else tail = current;
    // 将新插入的结点设置为首结点,同时修改当前位置
    head = current;
    current ++;
}

inline void insert_right(void)
{
    // 输入结点信息
    int x;
    cin >> x;
    // 创建一个新结点
    list[current] = x;
    l[current] = tail;
    r[current] = -1;
    // 修改原先的尾结点
    if(tail != -1) r[tail] = current;
    else head = current;
    // 将新插入的结点设置为尾结点,同时修改当前位置
    tail = current;
    current ++;
}

inline void delete_k(void)
{
    //输入部分
    int k;
    cin >> k;
    // 第一种情况,即该结点不是首结点也不是尾结点
    if(head != k - 1 && tail != k - 1)
    {
        // 找出该结点的前一个结点和后一个结点的下标
        int before = l[k - 1], after = r[k - 1];
        // 修改前一个结点的后一个元素下标和后一个结点的前一个元素下标
        r[before] = r[k - 1];
        l[after] = l[k - 1];
    }
    // 第二种情况,即该结点是首结点但是不是尾结点
    else if(head == k - 1 && tail != k - 1) 
    {
        head = r[k - 1];
        l[head] = -1;
    }
    // 第三种情况,即该结点是尾结点但是不是首结点
    else if(tail == k - 1 && head != k - 1)
    {
        tail = l[k - 1];
        r[tail] = -1;
    }
    // 第四种情况,该结点是链表中唯一结点
    else
    {
        head = -1;
        tail = -1;
    }
}

inline void insert_before_k(void)
{
    int k;
    cin >> k;
    if(head == k - 1) insert_left();
    else
    {
        int x;
        cin >> x;
        // 找到第k个结点的前一个结点
        int before = l[k - 1];
        // 创建一个新的结点
        list[current] = x;
        l[current] = before;
        r[current] = k - 1;
        // 修改前一个结点的后指针
        r[before] = current;
        // 修改第k个结点的前指针
        l[k - 1] = current;
        // 修改当前指针
        current ++;
    }
}

inline void insert_after_k(void)
{
    int k;
    cin >> k;
    if(tail == k - 1) insert_right();
    else
    {
        int x;
        cin >> x;
        // 找到第k个结点的后一个结点
        int after = r[k - 1];
        // 创建一个新的结点
        list[current] = x;
        l[current] = k - 1;
        r[current] = after;
        // 修改第k个结点的后指针
        r[k - 1] = current;
        // 修改后一个结点的前指针
        l[after] = current;
        // 修改当前指针
        current ++;
    }
}

int main(void)
{
    // 输入操作次数
    int M;
    cin >> M;
    // 输入每一次的操作,并分情况讨论
    for(int i = 0; i < M; ++i)
    {
        string operation;
        cin >> operation;
        if(operation == "L") insert_left();
        else if(operation == "R") insert_right();
        else if(operation == "D") delete_k();
        else if(operation == "IL") insert_before_k();
        else if(operation == "IR") insert_after_k();
    }
    // 循环输出整个链表
    while(head != -1)
    {
        cout << list[head] << " ";
        head = r[head];
    }
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB贝叶斯线性回归模型案例

采用辛烷值数据集“spectra_data.mat”(任意数据集均可),介绍贝叶斯线性回归模型的构建和使用流程。 运行结果如下: 训练集预测精度指标如下: 训练集数据的R2为: 1 训练集数据的MAE为: 0.00067884 训练集数据的RMSE为: 0.00088939 测试集预测精度指标如下: 测试集数据的R2…

Python学习之小游戏--坦克大作战

今天跟视频学习了Python实现坦克大作战小游戏&#xff0c;挺有意思的&#xff0c;一起来玩吧~ 按空格发射子弹&#xff0c;上下左右键实现移动&#xff0c;ESC键无限复活。 import pygame,time,random from pygame.sprite import Sprite SCREEN_WIDTH800 SCREEN_HEIGHT500 BG…

如何改善提示词,让 GPT-4 更高效准确地把视频内容整体转换成文章?

&#xff08;注&#xff1a;本文为小报童精选文章。已订阅小报童或加入知识星球「玉树芝兰」用户请勿重复付费&#xff09; 让我们来讨论一下大语言模型应用中的一个重要原则 ——「欲速则不达」。 作为一个自认为懒惰的人&#xff0c;我一直有一个愿望&#xff1a;完成视频制作…

typescript2-类的类型

/* 输出 吃饭 游泳 */ []( )继承与多态------------------------------------------------------------------------1. 子类继承父类特征子类 extends 父类2. 当需要父类参数传递时&#xff0c;用子类也可以&#xff0c;这就是多态/* 继承&#xff1a;子类继承父类 多态…

集团型企业组织架构复杂,业务线多,如何进行高效费用管控?

企业管理中流行这样一句话&#xff1a;“企业转型&#xff0c;财务先行”。对集团型企业而言&#xff0c;当今的发展形势下&#xff0c;通过财务战略全面转型、最终撬动企业价值提升&#xff0c;是一件难而正确的事情。 集团企业具有经营规模大、产业链多、分支机构多、地域跨度…

容器部署rabbitmq集群迁移

1、场景&#xff1a; 因业务需要&#xff0c;要求把rabbitmq-A集群上的数据迁移到rabbitmq-B集群上&#xff0c;rabbitmq的数据包括元数据&#xff08;RabbitMQ用户、vhost、队列、交换和绑定&#xff09;和消息数据&#xff0c;而消息数据存储在单独的消息存储库中。 2、迁移要…

中国算力网络市场发展分析

中国算力网络市场发展现状 算力涵盖计算、内存、存储等全方位能力&#xff0c;广泛分布于网络边缘、云计算中心、联网设备及转发节点。随着数字化技术革新&#xff0c;算力与网络正深度融合&#xff0c;推动“算网一体化”的演进。这一新型基础设施日渐凸显其重要性&#xff0c…

番外篇 | YOLOv8改进之即插即用全维度动态卷积ODConv + 更换Neck网络为GFPN

前言:Hello大家好,我是小哥谈。本文所做出的改进是在YOLOv8中引入即插即用全维度动态卷积ODConv和更换Neck网络为GFPN,希望大家学习之后能够有所收获~!🌈 目录 🚀1.基础概念 🚀2.网络结构 🚀3.添加步骤 🚀4.改进方法 🍀🍀步骤1:block.py文件修改…

Kamailio-Web管理页面Siremis的安装与部署

siremis 是针对于 Kamailio 的web管理接口&#xff0c;使用PHP书写&#xff0c;更新至2020年&#xff0c;相对不是太新但是是官方友链的 以下就采用 Ubuntu 22.04Siremis 5.8.0apache http server 2.4php7.0 如有疑问请参看官方指南 以下开始介绍操作步骤 安装apache2.4 we…

一文读懂什么是“GPU算力”

在数字化转型的浪潮中&#xff0c;各行业对算力的需求日益激增&#xff0c;GPU&#xff08;图形处理单元&#xff09;算力作为推动科技进步的重要力量&#xff0c;正逐步从传统的图形渲染领域扩展到人工智能、大数据分析、高性能计算等多个前沿领域。通过本文&#xff0c;深入剖…

亮相2024世界人工智能大会,扫描全能王AIGC“黑科技”助力敦煌遗书数字化修复

7月4日&#xff0c;2024年世界人工智能大会&#xff08;简称“大会”&#xff09;在上海举行。这次这场科技与创新的盛会上&#xff0c;一张古朴、典雅的卷轴吸引了众人的目光。这张被修复的卷轴脱胎于敦煌遗书系列古籍&#xff0c;在被机器拍摄扫描后&#xff0c;卷轴上脏污、…

Airflow: 大数据调度工具详解

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 欢迎关注微信公众号&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&a…

SalesForce集成案例-获取联系人信息

SalesForce本身比较复杂&#xff0c;涉及的东西比较多&#xff0c;下面以使用REST API接口为例&#xff0c;介绍与SalesForce集成的过程&#xff0c;集成案例&#xff1a;获取联系人信息。 首先需要注册一个免费的开发者帐号&#xff0c;具有完全操作SalesForce的权限。 1、注…

Echarts中的热力图和漏斗图(在Vue中使用热力图和漏斗图)

热力图 (Heatmap) Echarts的热力图用于展示两个维度数据矩阵中的值分布情况。它通过在平面上划分成多个矩形区域&#xff0c;并用不同的颜色填充这些区域来表示数据的大小或强度。颜色渐变从浅到深通常映射着数值从小到大&#xff0c;从而直观展示数据的集中程度和分布模式。热…

STM32工业自动化控制系统教程

目录 引言环境准备工业自动化控制系统基础代码实现&#xff1a;实现工业自动化控制系统 4.1 数据采集模块 4.2 数据处理与分析 4.3 控制系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;工业自动化与优化问题解决方案与优化收尾与总结 1. 引言 工业自动化控制系统利用…

INFINI Console 使用介绍

上次在《INFINI Easysearch尝鲜Hands on》中我们部署了两个节点的Easysearch&#xff0c;并且也设置了Console对集群进行监控。那么今天我们再来介绍下INFINI Console的使用。 INFINI Console 仪表盘功能介绍 INFINI Console 是一个功能强大的数据管理和分析平台&#xff0c;…

JBoss JMXInvokerServlet 反序列化漏洞

漏洞原理&#xff1a; 这是经典的JBoss反序列化漏洞&#xff0c;JBoss在/invoker/JMXInvokerServlet请求中读取了用户传入的对象&#xff0c;然后我们利用Apache Commons Collections中的Gadget执行任意代码。 影响版本&#xff1a; JBoss Enterprise Application Platform 6…

实时数仓Hologres OLAP场景核心能力介绍

作者&#xff1a;赵红梅 Hologres PD OLAP典型应用场景与痛点 首先介绍典型的OLAP场景以及在这些场景上的核心痛点&#xff0c;OLAP典型应用场景很多&#xff0c;总结有四类&#xff1a;第一类是BI报表分析类&#xff0c;例如BI报表&#xff0c;实时大屏&#xff0c;数据中台等…

Java项目:基于SSM框架实现的班主任助理管理系统【ssm+B/S架构+源码+数据库+开题报告+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的班主任助理管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、功…

iOS App 测试环境升级,遇到的问题以及解决方法

iOS App 测试环境升级&#xff0c;遇到的问题以及解决方法 Mac 实体机升级到 Sonima 14.5 Xcode 升级到 15.3 问题1&#xff1a; Xcode 编译 WebDriverAgent 失败 尝试下载 最新版本的WDA 源码编译&#xff0c;可以编译成功。 问题2&#xff1a;具体坐标直接点击的代码都会报错…