算法模板之双链表图文详解

在这里插入图片描述
🌈个人主页:聆风吟
🔥系列专栏:算法模板、数据结构
🔖少年有梦不应止于心动,更要付诸行动。


文章目录

  • 📋前言
  • 一. ⛳️使用数组模拟双链表讲解
    • 1.1 🔔为什么我们要使用数组去模拟双链表?
    • 1.2 🔔用数组模拟实现双链表
      • 1.2.1 👻整体框架说明
      • 1.2.2 👻双链表查找和修改
      • 1.2.3 👻双链表插入结点
      • 1.2.4 👻双链表删除结点
    • 1.3 🌟模板提取(重点)🌟
      • 1.3.1 👻有详细注释版
      • 1.3.1 👻无详细注释版
  • 二. ⛳️题目练习
    • 2.1 题目
    • 2.2 输入样例
    • 2.3 输出样例
    • 2.4 c++代码
  • 📝结语

📋前言

    💬 hello! 各位铁子们大家好哇,今天作者给大家带来的算法模板是使用数组模拟双链表,让我们一起加油进步。
    📚 系列专栏:本期文章收录在《算法模板》,大家有兴趣可以浏览和关注,后面将会有更多精彩内容!
    🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝



一. ⛳️使用数组模拟双链表讲解

1.1 🔔为什么我们要使用数组去模拟双链表?

    由于该问题已经在第一期《算法模板之单链表讲解》这篇文章中已经叙述过了,相信看过第一期的小伙伴应该已经知道,在这里就不多阐述,感兴趣的小伙伴可以自行跳转浏览。


1.2 🔔用数组模拟实现双链表

1.2.1 👻整体框架说明

初始状态:左边界结点指向右边界结点,右边界结点指向左边界结点
在这里插入图片描述


插入结点状态:

  • 创建数组valprene 分别存储某个结点的值以及它的前驱指针和后继指针;
  • 下标 0 和 1 分别存储边界结点;
  • 从下标 2 的位置开始插入结点;
  • 本文仅仅使用左右边界结点的指针,无需在意其中存的值。

    综上所述,真正的结点相当于从下标为2的位置开始往后所有插入的数,左右边界结点仅起到一个指针的效果。如下图的3,4,5,6为真正的结点。
在这里插入图片描述

1.2.2 👻双链表查找和修改

因为是使用数组模拟出来的链表,所以对于查找和修改直接通过数组下标进行遍历查找即可,这里就不多叙述。


1.2.3 👻双链表插入结点

在第k个结点的右边插入一个数 x:如下图在第2个结点后面插入一个数 7。
在这里插入图片描述

代码展示(建议结合图示看注释):

//在结点k的右边插入一个数x
void insert(int k, int x)
{
    //将待插值赋给新结点
    val[idx] = x;
    //将新结点分别指向插入位置的右结点和左结点
    ne[idx] = ne[k];
    pre[idx] = k;
    //将新结点的右边结点向左指向新结点
    pre[ne[k]] = idx;
    //将新结点的左边结点向右指向新结点
    ne[k] = idx;
    //更新结点索引
    idx++;
}

其他形式插入:在链表的最左端插入、最右端插入、在第k个结点的左边插入一个数 x
    在其他位置插入,大家可以按照上面的方式自行模拟。不过,在算法竞赛中如果每种插入方式都模拟一下,显然是太浪费时间了。仔细观察可以发现,我们仍然可以使用上面的insert(int k, int x)函数实现各种位置的插入,只需要稍微变动一下传入的 k 值。

  1. 在第k个结点的左边插入一个数 x: 如下图,在第2个结点的左边插入一个数7,可以转化为在第1个结点后面插入一个数7,执行语句:insert(pre[k], x) 即可。
    在这里插入图片描述

  1. 在链表的最左端插入一个数x: 如下图,在最左端插入一个数x,可以转化为在左边结点后面插入一个数x,执行 insert(0, x) 即可。
    在这里插入图片描述

  1. 在链表的最右端插入一个数x: 如下图,在最右端插入一个数x,可以转化为在右边界结点的左结点后面插入一个数x,执行 insert(pre[1], x) 即可。
    在这里插入图片描述

1.2.4 👻双链表删除结点

删除第k个结点
在这里插入图片描述

代码展示(建议结合图示看注释):

//删除第k个结点
void remove(int k)
{
    //将待删除结点的左结点的后继指针指向待删除结点的右结点
    ne[pre[k]] = ne[k];
    //将待删除结点的右结点的前驱指针指向待删除结点的左结点
    pre[ne[k]] = pre[k];
}

1.3 🌟模板提取(重点)🌟

1.3.1 👻有详细注释版

模板代码

// val[i] 表示结点i的值
// pre[i] 表示结点i的前驱指针
// ne[i] 表示结点i的后继指针
// idx 存储当前已经用到了哪个点,即记录当前下标位置
int val[N], pre[N], ne[N], idx;

//初始化
void init()
{
    //左边界结点指向右边界结点,右边界结点指向左边界结点
    ne[0] = 1;
    pre[1] = 0;
    //更新结点索引,因为下标0和1被左右边界结点占用。
    idx = 2;
}

//在结点k的右边插入一个数x
//只使用本函数可以通过改变k的值,实现其他形式的插入。
void insert(int k, int x)
{
    //将待插值赋给新结点
    val[idx] = x;
    //将新节点分别指向插入位置的右结点和左结点
    ne[idx] = ne[k];
    pre[idx] = k;
    //将新结点右边一节点向左指向新结点
    pre[ne[k]] = idx;
    //将新结点左边一节点向右指向新结点
    ne[k] = idx;
    //更新结点索引
    idx++;
}

//删除第k个结点
void remove(int k)
{
    //将待删除结点的左结点的后继指针指向待删除结点的右结点
    ne[pre[k]] = ne[k];
    //将待删除结点的右结点的前驱指针指向待删除结点的左结点
    pre[ne[k]] = pre[k];
}

1.3.1 👻无详细注释版

int val[N], pre[N], ne[N], idx;

//初始化
void init()
{
    ne[0] = 1;
    pre[1] = 0;
    idx = 2;
}

//在结点k的右边插入一个数x
void insert(int k, int x)
{
    val[idx] = x;
    ne[idx] = ne[k];
    pre[idx] = k;
    pre[ne[k]] = idx;
    ne[k] = idx;
    idx++;
}

//删除第k个结点
void remove(int k)
{
    ne[pre[k]] = ne[k];
    pre[ne[k]] = pre[k];
}


二. ⛳️题目练习

⌈ 在线OJ链接,可以转至此处自行练习 ⌋

2.1 题目

在这里插入图片描述

2.2 输入样例

10
R 7
D 1
L 3
IL 2 10
D 3
IL 2 7
L 8
R 9
IL 4 7
IR 2 2

2.3 输出样例

8 7 7 3 2 9

2.4 c++代码

#include<iostream>

using namespace std;

const int N = 100010;
int val[N], pre[N], ne[N], idx;

//初始化
void init()
{
    ne[0] = 1;
    pre[1] = 0;
    idx = 2;
}

//在结点k的右边插入一个数x
void insert(int k, int x)
{
    val[idx] = x;
    ne[idx] = ne[k];
    pre[idx] = k;
    pre[ne[k]] = idx;
    ne[k] = idx;
    idx++;
}

//删除第k个结点
void remove(int k)
{
    ne[pre[k]] = ne[k];
    pre[ne[k]] = pre[k];
}

int main()
{
    int m;
    cin >> m;
    
    init();//切记:不要忘记进行初始化
    
    while(m--)
    {
        int k, x;
        string op;
        
        cin >> op;
        //判断执行哪种操作
        if(op == "L")//在链表的最左端插入x
        {
            cin >> x;
            insert(0, x);
        }
        else if(op == "R")//在链表的最右端插入x
        {
            cin >> x;
            insert(pre[1], x);
        }
        else if(op == "D")//把第k个插入的数删除
        {
            cin >> k;
            remove(k+1);//因为初始化从下标为2位置开始插入结点,所以第k插入数的下标为k+2-1
        }
        else if(op == "IL")//第k个插入的数左侧插入一个数
        {
            cin >> k >> x;
            insert(pre[k+1], x);
        }
        else//第k个插入的数右侧插入一个数
        {
            cin >> k >> x;
            insert(k+1, x);
        }
    }
    
    //打印链表
    for(int i = ne[0]; i != 1; i = ne[i]) cout << val[i] << " ";
    cout << endl;
    
    return 0;
}


📝结语

     今天的干货分享到这里就结束啦!如果觉得文章还可以的话,希望能给个三连支持一下,聆风吟的主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的最大动力!
在这里插入图片描述

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

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

相关文章

全国巡展“2024人工智能展·世亚智博会”3月上海·4月杭州·6月北京

近年来&#xff0c;我国积极布局人工智能产业&#xff0c;竞跑“未来赛道”。随着各行业、各领域对人工智能需求的日益增长&#xff0c;与实体经济深度融合的新模式不断涌现&#xff0c;形成了具有中国特色的研发体系和应用生态&#xff0c;引领着经济社会各领域从数字化、网络…

YOLOv3-YOLOv8的一些总结

0 写在前面 这个文档主要总结YOLO系列的创新点&#xff0c;以YOLOv3为baseline。参考(抄)了不少博客&#xff0c;就自己看看吧。有些模型的trick不感兴趣就没写进来&#xff0c;核心的都写了。 YOLO系列的网络都由四个部分组成&#xff1a;Input、Backbone、Neck、Prediction…

高新技术企业工时管理的挑战与应对策略

随着科技的飞速发展&#xff0c;高新技术企业已成为推动社会进步的重要力量。而在这类企业中&#xff0c;工时管理作为企业管理的重要组成部分&#xff0c;其意义也日益凸显。有效的工时管理不仅关乎企业的项目进度、人力掌控和资源合理配置&#xff0c;还直接影响到企业的研发…

centos7服务器上的文件上传到谷歌云盘(google drive)

1,下载gdrive客户端&#xff0c;Releases glotlabs/gdrive GitHub 2&#xff0c;下载完解压,并移动到cp gdrive /usr/local/bin/ 3&#xff0c;查看是否安装成功 4,添加账户&#xff0c;gdrive account add 根据链接&#xff0c;创建Client id和 Client secret 5,填写Client…

spring boot 配置多数据源 踩坑 BindingException: Invalid bound statement (not found)

在上一篇&#xff1a;《【已解决】Spring Boot多数据源的时候&#xff0c;mybatis报错提示&#xff1a;Invalid bound statement (not found)》 凯哥(凯哥Java) 已经接受了&#xff0c;在Spring Boot配置多数据源时候&#xff0c;因为自己马虎&#xff0c;导致的一个坑。下面&a…

SEO专业人士成功所需的8大技能

你有能力在SEO领域建立职业生涯吗&#xff1f;您需要某些技能才能成功。在这里了解这些技能是什么。 尽管SEO已经存在了几十年&#xff0c;但许多大学仍然没有教授SEO&#xff0c;也没有在大多数营销课程中提及。 SEO专业人士来自不同的背景。有些是程序员&#xff0c;有些是…

IDA PRO 0A - 交叉引用

本文将讨论IDA中的交叉引用的相关知识。 更多c逆向知识可以看B站的课程《C 反汇编基础教程(IDA Pro Visual Studio)》 交叉引用 IDA 中的交叉引用通常简称为xref 。从名字可以看出&#xff0c;使用快捷键就可以找出某个函数或者数据被引用的地方。 在IDA 中有两类基本的交叉引…

NSSCTF第16页(3)

[SWPUCTF 2023 秋季新生赛]ez_talk 上传一句话木马得到 抓包改文件类型 上传成功&#xff0c;只是倒序而已 得到flag [第五空间 2021]PNG图片转换器 这道题采用的是ruby语言&#xff0c;第一次听说 2021-第五空间智能安全大赛-PNG图片转换器 | 管道符与反引号的配合、open…

使用python实现链表

手写代码 class Node(object):def __init__(self, item):self.item itemself.next Noneclass LinkListFunction(object):"""此对象为Node对象的方法类"""def __init__(self):self.linklistlength 0 # 当前链表的长度def create_linklist_he…

C语言学习第二十六天(算法的时间复杂度和空间复杂度)

1、算法效率 衡量一个算法的好坏&#xff0c;是从时间和空间两个方面来衡量的&#xff0c;换句话说就是从时间复杂度和空间复杂度来衡量的 这里需要补充一点&#xff1a;时间复杂度是衡量一个算法的运行快慢&#xff0c;空间复杂度是主要衡量一个算法运行所需要的额外空间。 …

「Verilog学习笔记」交通灯

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 timescale 1ns/1nsmodule triffic_light(input rst_n, //异位复位信号&#xff0c;低电平有效input clk, //时钟信号input pass_request,output wire[7:0]clock,output reg…

Shared Worker的快速理解与简单应用

SharedWorker 是 HTML5 中引入的一种 WebWorkers 类型&#xff0c;用于在浏览器中创建可在多个浏览器窗口或标签页之间共享的后台线程。Web Workers 是在主线程之外运行的脚本&#xff0c;允许执行一些耗时的任务而不会阻塞用户界面。 对 SharedWorker 的概念、理解和应用的简要…

2023第十七届中国品牌节,酷开科技荣获金谱奖!

11月18日&#xff0c;以“复苏与腾飞”为主题的2023第十七届中国品牌节&#xff0c;在杭州市云栖小镇国际会展中心盛大开幕。来自政界、商界、文化界等领域的6000余名嘉宾出席本次盛会&#xff0c;共同见证了民族品牌的崛起&#xff0c;全力奉献一场史无前例的“品牌人的亚运会…

Pikachu漏洞练习平台之暴力破解(基于burpsuite)

从来没有哪个时代的黑客像今天一样热衷于猜解密码 ---奥斯特洛夫斯基 Burte Force&#xff08;暴力破解&#xff09;概述 “暴力破解”是一攻击具手段&#xff0c;在web攻击中&#xff0c;一般会使用这种手段对应用系统的认证信息进行获取。 其过程就是使用大量的认证信息在认…

【操作系统】实验名称: 实验五 文件系统

实验目的&#xff1a; 1. 掌握文件系统的基本概念和工作机制 2. 掌握文件系统的主要数据结构的实现 3、掌握软件系统实现算法 实验内容&#xff1a; 设计并实现一个虚拟的一级&#xff08;单用户&#xff09;文件系统程序 提供以下操作 1、文件创建/删除接口命令 2、目录创建/删…

合并 K 个排序链表——Java解答

题目&#xff1a;合并 K 个排序链表 题目描述&#xff1a; 给你一个链表数组&#xff0c;每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 示例&#xff1a; 假设有以下三个链表&#xff1a; 1->4->5, 1->3->4,…

QUIC在零信任解决方案的落地实践

一 前言 ZTNA为以“网络为中心”的传统企业体系架构向以“身份为中心”的新型企业安全体系架构转变&#xff0c;提供解决方案。随着传统网络边界不断弱化&#xff0c;企业SaaS规模化日益增多&#xff0c;给终端安全访问接入创造了多元化的空间。其中BYOD办公方式尤为突出&#…

SpringBoot使用@DS配置 多数据源 【mybatisplus druid datasource mysql】

项目最近需要使用多数据源&#xff0c;不同的mapper分别读取不同的链接&#xff0c;本项目使用了mybatisplus druid 来配置多数据源&#xff0c;基于mysql数据库。 目录 1.引入依赖 ​2.配置文件 application.yaml 3.Mapper中使用DS切换数据源 4.使用DS的注意事项 1.引入依…

苹果忽略iPhone?2024可穿戴产品或成重心!

一代版本一代神&#xff0c;即便是强如iPhone也有着被忽视的一天&#xff0c;当然&#xff0c;这么说有些夸张。虽然iPhone永远都是苹果最重要的产品&#xff0c;但在明年&#xff0c;苹果的重心将偏向其他产品。 彭博社记者马克古曼&#xff08;Mark Gurman&#xff09;在新一…

如何确保对称密钥管理的存储安全?

确保对称密钥管理的存储安全是保障信息安全的重要一环。以下是一些建议&#xff0c;以确保对称密钥管理的存储安全&#xff1a; 使用安全存储设备&#xff1a;选择使用经过验证的安全存储设备来存储对称密钥。这些设备通常具有高度的物理安全性&#xff0c;可以防止未经授权的访…
最新文章