双链表

这篇具有很好参考价值的文章主要介绍了双链表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、算法描述

本篇文章讲述的数据结构是双链表,与上一篇文章一样是算法竞赛中常用的用数组模拟的双链表。

//用数组模拟的双链表定义如下:
int e[N], l[N], r[N], idx;

/*
	e[i]表示节点i的值
	l[i]表示节点i的左边一个节点
	r[i]表示节点i的右边一个节点
	idx表示当前用到了哪个节点
*/
  • 跟单链表差不多。
  • 多画图,多思考。

接下来介绍双链表的各种操作:

初始化操作:

void init()
{
    r[0] = 1, l[1] = 0, idx = 2;
}
  • \(0\)\(1\) 为两个界限,初始状态就是 \(0\) 的右边是 \(1\)\(1\) 的左边是 \(0\)
  • 要注意 \(idx\)\(2\) 开始。

在第k个节点右边插入:

void add(int k, int x)	//在第k个节点的右边插入一个新节点
{
    e[idx] = x;
    
    r[idx] = r[k], l[r[k]] = idx;
    
    l[idx] = k, r[k] = idx ++ ;
}
  • \(e[idx] = x\) 表示新节点的值为 \(x\)
  • \(r[idx] = r[k], l[r[k]] = idx;\) 表示新节点的下一个节点指向 \(k\) 节点的下一个节点 \(p\) ,然后 \(p\) 的前一个节点又指向新节点。
  • \(l[idx] = k, r[k] = idx;\) 表示新节点的左节点为 \(k\)\(k\) 节点的右节点指向 新节点。
  • \(idx ++ ;\) 表示当前节点已经被用了,待使用的节点是下一个。
  • 如何在左边插入呢?显然只需要修改一下参数即可:add(l[k], x)
  • 建议画图来理解。

删除第 \(k\) 个节点:

void remove(int k)
{
    r[l[k]] = r[k];
    l[r[k]] = l[k];
}
  • 数组删除不需要管内存泄漏的问题。
  • 假设用 \(p, k, q\) 来表示三个节点:
  • \(r[l[k]] = r[k];\) 表示 \(p\) 的右边指向 \(k\) 的右边,即 \(q\)
  • \(l[r[k]] = l[k];\) 表示 \(q\) 的左边指向 \(k\) 的左边,即 \(p\)
  • 画图来理解。

如何遍历呢?

for (int i = r[0]; i != 1; i = r[i])	cout << e[i] << ' ';
for (int i = l[1]; i != 0; i = l[i])	cout << e[i] << ' ';
  • 第一行是从左往右遍历,第二行是从右往左遍历。
  • \(0\)\(1\) 是两个界限,所以是从 \(r[0]\)\(l[1]\) 开始,而不是从 \(0\)\(1\) 开始。

链表的问题都需要读者多画图、多思考,也要多复习。

二、题目描述

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

  1. 在最左侧插入一个数;
  2. 在最右侧插入一个数;
  3. 将第 \(k\) 个插入的数删除;
  4. 在第 \(k\) 个插入的数左侧插入一个数;
  5. 在第 \(k\) 个插入的数右侧插入一个数

现在要对该链表进行 \(M\) 次操作,进行完所有操作后,从左到右输出整个链表。

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

输入格式

第一行包含整数 \(M\),表示操作次数。

接下来 \(M\) 行,每行包含一个操作命令,操作命令可能为以下几种:

  1. L x,表示在链表的最左端插入数 \(x\)
  2. R x,表示在链表的最右端插入数 \(x\)
  3. D k,表示将第 \(k\) 个插入的数删除。
  4. IL k x,表示在第 \(k\) 个插入的数左侧插入一个数。
  5. IR k x,表示在第 \(k\) 个插入的数右侧插入一个数。

输出格式

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

数据范围

\(1≤M≤100000\)
所有操作保证合法。文章来源地址https://www.toymoban.com/news/detail-747184.html

输入样例:

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 

输出样例:

8 7 7 3 2 9 

三、题目来源

AcWing算法基础课-827.双链表

四、源代码

#include <iostream>
#include <cstring>

using namespace std;

const int N = 100010;

int e[N], l[N], r[N], idx;

void init()
{
    l[1] = 0, r[0] = 1, idx = 2;
}

void add(int k, int x)
{
    e[idx] = x;
    
    r[idx] = r[k], l[r[k]] = idx;
    
    l[idx] = k, r[k] = idx ++ ;
}

void remove(int k)
{
    r[l[k]] = r[k];
    l[r[k]] = l[k];
}

int main()
{
    int m;
    cin >> m;
    
    init();
    
    while (m -- )
    {
        char s[10];
        cin >> s;
        
        int k, x;
        
        if (!strcmp(s, "L"))
        {
            cin >> x;
            add(0, x);
        }
        else if (!strcmp(s, "R"))
        {
            cin >> x;
            add(l[1], x);
        }
        else if (!strcmp(s, "D"))
        {
            cin >> k;
            remove(k + 1);
        }
        else if (!strcmp(s, "IL"))
        {
            cin >> k >> x;
            add(l[k + 1], x);
        }
        else
        {
            cin >> k >> x;
            add(k + 1, x);
        }
    }
    
    for (int i = r[0]; i != 1; i = r[i])    cout << e[i] << ' ';
    
    return 0;
}

/*
本题目并非完全照抄以上函数,还是需要处理一些问题的。
例如:删除第k个数,idx是从2开始使用的,所以删除的时候应该是remove(k + 1);
还有其他问题,读者可自行思考。
*/

到了这里,关于双链表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 手撕数据结构与算法——树(三指针描述一棵树)

    📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段, 因为最近参加新星计划算法赛道(白佬),所以加快了脚步,果然急迫感会增加动力 ——目标Windows,MySQL,Qt,数据结构与算法,Linux,多线程,会持续分享学习成果和小项目的 📖作者主页:king南星 📖

    2024年01月17日
    浏览(54)
  • 《数据结构、算法与应用C++语言描述》-列车车厢重排问题

    完整可编译运行代码见:Github::Data-Structures-Algorithms-and-Applications/_10Train_carriages_rearrangement/ 一列货运列车有 n 节车厢,每节车厢要停靠在不同的车站。假设 n个车站从 1 到n 编号,而且货运列车按照从n到1的顺序经过车站。车厢的编号与它们要停靠的车站编号相同。为了便于从

    2024年04月10日
    浏览(61)
  • 数据结构:定长顺序串(SString)基本操作的算法描述(C语言)

    作者在学习数据结构时,发现鲜有完全按照 C 语言描述的算法操作,这让习惯于写 .c 而不是 .cpp 的初学者很是头疼。本文将基于 C 语言描述算法操作,如有错漏还望大佬们指正。 本文将按照严惠敏所著《数据结构(C语言版)》所做的函数原型声明进行算法描述,由于C语言不支

    2024年02月07日
    浏览(69)
  • 数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。

    最短路径的算法有两个, Dijkstra算法 和 Floyd算法 。 Dijkstra算法 解决的是 单源 最短路径问题 。 Floyd算法解决的是 多源 最短路径问题,并且可以处理负权图 。 今天要讲的就是Dijkstra算法。 加: feng--Insist (大写的i),进java交流群讨论互联网+技术。可索要PPT等资料。 其他资料

    2024年02月11日
    浏览(51)
  • 数据结构学习记录——图应用实例-拯救007(问题描述、解题思路、伪代码解读、C语言算法实现)

    目录 问题描述  解题思路 伪代码  总体算法 DFS算法 伪代码解读 总体算法 DFS算法 具体实现(C语言) 在老电影“007之生死关头”(Live and Let Die)中有一个情节,007被毒贩抓到一个鳄鱼池中心的小岛上,他用了一种极为大胆的方法逃脱 —— 直接踩着池子里一系列鳄鱼的大脑

    2024年02月05日
    浏览(73)
  • 数据结构--双链表

    单链表 VS 双链表 单链表:无法逆向检索,有时候不太方便 双链表:可进可退,存储密度更低一丢丢 在p结点之后插入s结点 特殊处理:p是最后一个结点 用后插操作实现结点的插入有什么好处? 按位序插入前插操作: 找到前一个结点进行后插操作 ####删除p的后继结点q 特殊处

    2024年02月11日
    浏览(38)
  • 【数据结构】双链表

     带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了。 1.准备工作  由于实际开发项目中,项目的实现都是采用模

    2024年02月14日
    浏览(38)
  • 数据结构——双链表

    我宁愿靠自己的力量,打开我的前途,而不愿求有力者垂青  文章目录 双线向链表各接口函数名或变量名  双向链表接口实现源码 快速索引【头文件及函数声明】 双向链表接口实现 双向链表的构造分析 双向链表的定义及初始化 双向链表的插入和删除 往期回顾: 数据结构

    2024年02月11日
    浏览(39)
  • 数据结构之双链表

    双链表的思路和单链表大同小异,就是多加了一个前驱指针,希望大家好好学习双链表的代码

    2024年02月07日
    浏览(45)
  • 【数据结构初阶】双链表

    1.1结口实现 1.2申请结点 1.3初始化双链表 1.4打印双链表 1.5尾插 1.6尾删 1.7头插 1.8头删 1.9计算大小 1.10查找 1.11pos位置插入 1.12删除pos位置 1.12删除双链表 List.h List.c test.c 💘不知不觉,【数据结构初阶】双链表 以告一段落。通读全文的你肯定收获满满,让我们继续为数据结构学

    2024年02月05日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包