双链表——AcWing.827双链表

双链表

定义

双链表是链表的一种,它的每个节点有两个指针,一个指向前一个节点,一个指向后一个节点。这样使得链表可以双向遍历。

运用情况

  • 频繁进行前后双向遍历操作时非常有用,比如在一些需要来回移动处理数据的场景。
  • 可以方便地实现诸如栈、队列等数据结构的混合操作。
  • 在一些需要快速插入和删除节点,同时又需要双向遍历的特定算法和程序中经常被采用。

注意事项

  • 内存管理要恰当,确保正确地分配和释放节点内存,避免内存泄漏或非法访问。
  • 对节点指针的操作要格外小心,防止出现悬空指针或错误指向。
  • 在进行插入、删除等操作时,要注意前后节点指针的正确更新,保持链表的完整性。

解题思路

当使用双链表解决问题时,一般思路如下:

  • 明确问题中涉及到的操作,比如插入、删除、遍历等。
  • 根据操作确定如何更新节点的前后指针以维持链表结构。
  • 在进行复杂操作时,仔细考虑边界情况和特殊情况,确保算法的正确性和鲁棒性。
  • 可以借助一些辅助指针或变量来方便地进行节点的定位和操作。例如,在寻找特定节点时,可以利用前后向的遍历。
  • 对于一些需要高效操作的场景,优化指针的操作顺序和算法流程以提高性能。

AcWing.827双链表

题目描述

827. 双链表 - AcWing题库

运行代码

#include <iostream>
using namespace std;
const int N = 100010;
int l[N], r[N], idx, e[N];
int n;
void init()
{
    r[0] = 1, l[1] = 0, idx = 2;
}
void insert(int k, int x)
{
    e[idx] = x;
    l[idx] = k, r[idx] = r[k];
    l[r[k]] = idx, r[k] = idx ++ ;
}
void Remove(int k)
{
    l[r[k]] = l[k];
    r[l[k]] = r[k];
}
int main()
{
    init();
    cin >> n;
    while(n -- )
    {
        string op;
        int k, x;
        cin >> op;
        if(op == "L")
        {
            cin >> x;
            insert(0, x);
        }
        else if(op == "R")
        {
            cin >> x;
            insert(l[1], x);
        }
        else if(op == "IL")
        {
            cin >> k >> x;
            insert(l[k + 1], x);
        }
        else if(op == "IR")
        {
            cin >> k >> x;
            insert(k + 1, x);
        }
        else 
        {
            cin >> k;
            Remove(k + 1);
        }
    }
    for(int i = r[0]; i != 1; i = r[i]) cout << e[i] << ' ';    
    return 0;
}

代码思路

  1. 初始化:
    • 使用两个数组lr来分别存储每个节点的左指针和右指针。
    • 数组e用于存储每个节点的值。
    • idx用于追踪下一个要插入的节点的索引。
    • init()函数初始化双链表,将第一个虚拟节点(通常用作头节点)的右指针指向第二个虚拟节点(通常用作尾节点的前一个节点),并将第二个虚拟节点的左指针指向第一个虚拟节点。
  2. 插入操作:
    • insert(int k, int x)函数用于在给定节点k的右侧插入一个新节点,其值为x
    • 首先,将新节点的值存储在e[idx]中。
    • 然后,更新l[idx]r[idx]以指向正确的邻居节点。
    • 同时,更新k的右邻居和idx的左邻居的指针,使其指向新节点。
    • 最后,递增idx以准备下一次插入。
  3. 删除操作:
    • Remove(int k)函数用于删除给定节点k(注意:这里的k是节点在数组中的索引,而不是节点值)。
    • 通过更新k的左邻居的右指针和k的右邻居的左指针,来删除节点k
    • 注意:这里没有显式地释放或重置数组e中的值,因为C++的数组不会自动管理内存。但由于e是静态分配的,它将在程序结束时自动被销毁。
  4. 主函数:
    • 读取一个整数n,表示将要进行的操作数。
    • 对于每个操作,读取一个操作码op和一个或两个参数(取决于操作)。
    • 根据操作码执行相应的操作:
      • "L": 在双链表的左侧插入一个新节点。
      • "R": 在双链表的右侧插入一个新节点。
      • "IL": 在第k个节点的左侧插入一个新节点。
      • "IR": 在第k个节点的右侧插入一个新节点。
      • 其他: 删除第k个节点。
    • 在所有操作完成后,遍历并打印双链表中的节点值。

注意

  • 这里的节点索引是从虚拟头节点(索引为0)和虚拟尾节点的前一个节点(索引为1)开始的。因此,当插入或删除节点时,需要使用k + 1来引用实际的节点索引(从2开始)。
  • 代码没有包含错误检查,例如检查k是否超出了链表的合法范围。在实际应用中,应添加这些检查以防止程序崩溃或产生不可预测的行为。

改进思路

  1. 添加错误处理
    • 在进行插入或删除操作时,检查给定的索引k是否在链表的有效范围内。
    • 检查操作是否符合预期,比如尝试在已经不存在的节点上进行操作。
  2. 使用结构体或类
    • 创建一个结构体或类来表示链表节点,这样可以使代码更加清晰,并减少错误的可能性。
    • 在这个结构体或类中,可以包含节点的值、左指针和右指针。
  3. 封装链表操作
    • 将链表的操作(如插入、删除、遍历等)封装到类的方法中,这样可以使代码更加模块化。
    • 封装后的代码可以提供更好的封装性、继承性和多态性。
  4. 使用迭代器或指针
    • 考虑使用迭代器或指针来遍历链表,而不是直接使用数组索引。这可以使代码更加灵活,并减少错误的可能性。
  5. 改进输入验证
    • main函数中,添加对输入数据的验证,确保输入的操作码和参数是有效的。
    • 可以使用std::cin.fail()或类似的函数来检查输入是否成功。
  6. 使用标准库容器
    • 如果可能的话,考虑使用C++标准库中的容器(如std::list)来实现链表。这样可以减少手动管理内存和指针的复杂性,并提高代码的可读性和可维护性。
  7. 改进遍历打印逻辑
    • 遍历链表时,可以使用循环而不是递归,以提高效率。
    • 在打印链表时,可以添加一些分隔符或换行符,使输出更加清晰。
  8. 优化内存使用
    • 如果链表中的节点数量非常大,可以考虑使用动态内存分配来减少内存使用。
    • 但是,请注意,动态内存分配也会增加内存泄漏和指针错误的风险。
  9. 添加注释和文档:为代码添加注释,解释每个函数、类和变量的作用。编写文档,描述如何使用这个链表类,以及它的特性和限制。
  10. 使用异常处理:如果在链表操作中发生错误(如无效索引、无效操作等),可以使用C++的异常处理机制来抛出异常,并在调用者处捕获和处理这些异常。这可以使错误处理更加清晰和一致。

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

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

相关文章

嵌入式学习——Linux高级编程复习(TCP编程)——day44

基于TCP聊天: clientA.c clientB.c socket socket connect bind listen acce…

2024年了! 为什么还在用串口服务器?

在数字化飞速发展的2024年&#xff0c;串口服务器这一看似古老的技术仍然在工业自动化、远程监控和数据通信等领域发挥着重要作用。本文将从串口服务器的定义、功能、优势和使用场景四个方面来探讨&#xff0c;为什么串口服务器在今天仍然被广泛使用。 1. 什么是串口服务器 串口…

基于51单片机的红外计数器-1602显示

一.硬件方案 本设计的主要原理为&#xff1a;红外发射管发射红外线&#xff0c;红外接收管接收红外线&#xff0c;并且接收管当有红外线照射的时候&#xff0c;电阻比较小&#xff0c;当无线外线照射的时候电阻比较大&#xff0c;这样就可以通过一个电压比较器和一个基准电压进…

线程池ThreadPoolExecutor使用指南

线程池ThreadPoolExecutor使用指南 &#x1f9d0;使用线程池的好处是什么&#xff1f; 统一管理&#xff0c;减少资源获取创建的开销&#xff0c;提高利用率。 &#x1f527;线程池的参数 ​ThreadPoolExecutor​ 3 个最重要的参数&#xff1a; ​corePoolSize​ : 任务队列…

Linux系统编程:基础IO

目录 1.C语言文件回顾 2.系统文件I/O 2.1 系统接口介绍 2.2 文件描述符fd 2.3 重定向 2.4 理解缓冲区 2.5 理解文件系统 1.C语言文件回顾 在学习系统文件的操作之前&#xff0c;还记得C语言是如何进行对文件的操作的吗&#xff1f;下面看C语言接口&…

浪潮信息打造业界首款50℃进液温度服务器 PUE逼近理论极限1.0!

在科技飞速发展的今天&#xff0c;浪潮信息以其前瞻性的技术创新思维&#xff0c;再次突破行业极限&#xff0c;推出业界首个支持50℃进液温度的浸没式液冷服务器NF5180G7。这一创新成果不仅展现了浪潮信息在液冷技术领域的深厚实力&#xff0c;更标志着服务器冷却技术的一次重…

【2024亲测无坑】在Centos.7虚拟机上安装Oracle 19C

目录 一、安装环境准备 1、linux虚拟机安装 2、虚拟机快照 3、空间检查&软件上传 二、Oracle软件安装 1.preinstall安装及其他配置准备 2.oracle安装 三、数据库实例的安装 1.netca——网络配置助手 2.dbca——数据库配置助手 四、ORACLE 19C 在linux centos 7上…

基于PPO的强化学习超级马里奥自动通关

目录 一、环境准备 二、训练思路 1.训练初期&#xff1a; 2.思路整理及改进&#xff1a; 思路一&#xff1a; 思路二&#xff1a; 思路三&#xff1a; 思路四&#xff1a; 3.训练效果&#xff1a; 三、结果分析 四、完整代码 训练代码&#xff1a; 测试代码&#…

MySQL 日志(二)

本篇将继续介绍MySQL日志的相关内容 目录 一、二进制日志 简介 注意事项 删除二进制日志 查看二进制日志 二进制日志的格式 二、服务器日志维护 一、二进制日志 简介 二进制日志中主要记录了MySQL的更改事件&#xff08;不包含SELECT和SHOW),例如&#xff1a;表的…

Base64编码的工作原理与实际应用

目录 前言 一、什么是Base64编码&#xff1f; 二、Base64编码的原理 三、Base64编码的应用场景 四、为什么要使用Base 64 五、Base64加密解密的实现 前言 当你需要将二进制数据转换为可传输和存储的文本格式时&#xff0c;Base64编码是一个常用的选择。在这篇博客中&#…

C++ 51 之 继承中的构造和析构

对象构造和析构的调用原则 继承中的构造和析构 子类对象在创建时会首先调用父类的构造函数父类构造函数执行完毕后&#xff0c;才会调用子类的构造函数当父类构造函数有参数时&#xff0c;需要在子类初始化列表(参数列表)中显示调用父类构造函数析构函数调用顺序和构造函数相…

可以用来制作硬模空心耳机壳的胶粘剂有哪些种类?

可以用来制作硬模空心耳机壳的胶粘剂有哪些种类&#xff1f; 制作耳机壳的胶粘剂有很多种类&#xff0c;常见的有环氧树脂胶水、UV树脂胶、快干胶、热熔胶等。 这些胶粘剂都有不同的特点和适用场景&#xff0c;可以根据自己的需求选择合适的类型。 例如&#xff1a; 环氧树脂…

Adobe设计替代软件精选列表

Adobe软件的替代列表&#xff0c;最初由 XdanielArt 收集&#xff0c;并由社区改进。您可以随意打开问题或拉出请求&#xff0c;或从数据中创建图像(以便于共享)。列表总是按照免费和开源选项的顺序排列&#xff0c;但根据您的用例&#xff0c;它可能不是最佳选择 替代因素 &am…

Python 潮流周刊#56:NumPy 2.0 里更快速的字符串函数

△△请给“Python猫”加星标 &#xff0c;以免错过文章推送 本周刊由 Python猫 出品&#xff0c;精心筛选国内外的 250 信息源&#xff0c;为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景&#xff1a;帮助所有读者精进 Python 技术&am…

【linux】认识“文件”的本质,理解“文件系统”的设计逻辑,体会linux优雅的设计理念

⭐⭐⭐个人主页⭐⭐⭐ ~~~~~~~~~~~~~~~~~~ C站最❤❤❤萌❤❤❤博主 ~~~~~~~~~~~~~~~~~~~ ​♥东洛的克莱斯韦克-CSDN博客♥ ~~~~~~~~~~~~~~~~~~~~ 嗷呜~ ✌✌✌✌ 萌妹统治世界~ &#x1f389;&#x1f389;&#x1f389;&#x1f389; ✈✈✈✈相关文章✈✈✈✈ &#x1f4a…

2023年的Top20 AI应用在近一年表现怎么样?

AI应用现在进入寒武纪大爆发时代&#xff0c;百花争艳。如果倒回到2023年初&#xff0c;那时候排名靠前的AI应用在一年多时间&#xff0c;发生了哪些变化&#xff1f;能带给我们什么启示&#xff1f; 在2023年1月&#xff0c;排名靠前20的AI应用是&#xff1a; DeepL&#xff…

MATLAB中与直方图有关函数的关系

histogram Histogram plot画直方图 histcounts 直方图 bin 计数 histcounts是histogram的主要计算函数。 discretize 将数据划分为 bin 或类别 histogram2 画二元直方图 histcounts2 二元直方图 bin 计数 hist和histc过时了。替换不建议使用的 hist 和 histc 实例 hist → \r…

Day54 JDBC

Day54 JDBC JDBC&#xff1a;SUN公司提供的一套操作数据库的标准规范&#xff0c;就是使用Java语言操作关系型数据库的一套API JDBC与数据库驱动的关系&#xff1a;接口与实现的关系 给大家画一个jdbc的工作模式图 1.JDBC的四大金刚 1.DriverManager&#xff1a;用于注册驱动 2…

【Quartus 13.0】NIOS II 部署UART 和 PWM

打算在 EP1C3T144I7 芯片上部署 nios ii 做 uart & pwm控制 这个芯片或许不够做 QT 部署 这个芯片好老啊&#xff0c;但是做控制足够了&#xff0c;我只是想装13写 leader给的接口代码是用VHDL写的&#xff0c;我不会 当然verilog我也不太会 就这样&#xff0c;随便写吧 co…

SUSTAINABILITY,SCIESSCI双检期刊还能投吗?

本期&#xff0c;小编给大家介绍的是一本MDPI出版社旗下SCIE&SSCI双检“毕业神刊”——SUSTAINABILITY。据悉&#xff0c;早在2024年1月&#xff0c;ElSEVIER旗下的Scopus数据库已暂停收录检索期刊SUSTAINABILITY所发表文章&#xff0c;同时重新评估是否继续收录该期刊。随…