当前位置: 首页 > news >正文

手撕算法——链表

算法基础——链表-CSDN博客

一、排队顺序

题⽬来源:洛⾕

题⽬链接:B3630 排队顺序 - 洛谷

难度系数:★

1. 题目描述

2. 算法原理

        本题相当于告诉了我们每⼀个点的后继,使⽤静态链表的存储⽅式能够很好的还原这个队列。

        数组 [1, n的下标可以当做据域,根据题意修指针域即可。

 

注意:可以不需要 e[N] 数组,输出下标即可 

3. 参考代码 

#include <iostream>

using namespace std;

const int N = 1e6 + 10;

int n, h;
int ne[N];

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> ne[i];
    cin >> h;
    
    // 遍历链表
    for(int i = h; i; i = ne[i])
    {
        cout << i << " ";
    }

    return 0;
}

二、单向链表

题⽬来源:洛⾕

题⽬链接:B3631 单向链表 - 洛谷

难度系数:★

1. 题目描述

2. 算法原理

        链表模板题,直接实现⼀个单链表即可。

3. 参考代码

#include <iostream>

using namespace std;

const int N = 1e5 + 10, M = 1e6 + 10;

// 链表
int h, id, e[N], ne[N];
int mp[M]; // mp[i] 用来标记 i 这个元素存在什么位置

int main()
{
    int q; cin >> q;

    // 初始化
    id++;
    e[id] = 1;
    mp[1] = id;

    while(q--)
    {
        int op, x, y;
        cin >> op >> x;
        int p = mp[x]; // x 存的位置

        if(op == 1) // x 后面插入
        {
            cin >> y;

            id++;
            e[id] = y;
            ne[id] = ne[p];
            ne[p] = id;

            mp[y] = id; // 标记 y 这个元素存的位置
        }
        else if(op == 2) // 查询 x 后面的元素
        {
            cout << e[ne[p]] << endl;
        }
        else // 删除 x 后面的元素
        {
            ne[p] = ne[ne[p]];
        }
    }

    return 0;
}

三、队列安排

题⽬来源:洛⾕

题⽬链接:P1160 队列安排 - 洛谷

难度系数:★★

1. 题目描述

2. 算法原理

        频繁的在某⼀个位置之前和之后插⼊元素,因此可以⽤双向循环的链表来模拟。

3. 参考代码

#include <iostream>

using namespace std;

const int N = 1e5 + 10;

// 双向链表
int h, pre[N], ne[N];
bool st[N]; // st[x] 表示 x 这个元素是否已经被删除

int n, m;

int main()
{
    cin >> n;
    // 初始化
    pre[1] = h;
    ne[h] = 1;

    for(int i = 2; i <= n; i++)
    {
        int k, p; cin >> k >> p;
        if(p == 0)
        {
            // i 放在 k 的左边
            ne[i] = k;
            pre[i] = pre[k];
            ne[pre[k]] = i;
            pre[k] = i;
        }
        else
        {
            // i 放在 k 的右边
            pre[i] = k;
            ne[i] = ne[k];
            pre[ne[k]] = i;
            ne[k] = i;
        }
    }

    cin >> m;
    while(m--)
    {
        int x; cin >> x;
        // 将 x 删除
        if(st[x] == true) continue;

        ne[pre[x]] = ne[x];
        pre[ne[x]] = pre[x];
        st[x] = true; // 标记 x 已经被删除
    }

    for(int i = ne[h]; i; i = ne[i])
    {
        cout << i << " ";
    }


    return 0;
}

四、约瑟夫问题

题⽬来源:洛⾕

题⽬链接:P1996 约瑟夫问题 - 洛谷

难度系数:★

1. 题目描述

2. 算法原理

        使⽤循环链表模拟即可。

3. 参考代码

#include <iostream>

using namespace std;

const int N = 110;

int n, m;
int ne[N];

int main()
{
    cin >> n >> m;
    // 创建循环链表
    for(int i = 1; i < n; i++) ne[i] = i + 1;
    ne[n] = 1;

    // 模拟约瑟夫游戏的过程
    int t = n;
    for(int i = 1; i <= n; i++) // 执行 n 次出圈操作
    {
        for(int j = 1; j < m; j++) // 让 t 向后移动 m - 1 次
        {
            t = ne[t];
        }

        cout << ne[t] << " ";
        ne[t] = ne[ne[t]];
    }

    return 0;
}

相关文章:

  • 基于springboot的“衣依”服装销售平台(043)
  • linux_git使用
  • 【Json RPC框架】框架介绍与环境搭建(Ubuntu 22.04)
  • 【Docker系列五】Docker Compose 简介
  • 汽车制造MES
  • JavaScript | 爬虫逆向 | 语法基础| 01
  • MATLAB入门
  • React的状态管理——Redux
  • CE设备(Customer Edge device,用户边缘设备)
  • Vue 项目编译错误:These dependencies were not found,To install them, you can run...
  • 群体智能优化算法-蜻蜓优化算法(Dragonfly Algorithm, DA,含Matlab源代码)
  • “统计视角看世界”专栏导读
  • 本地安装deepseek大模型,并使用 python 调用
  • 深度学习框架PyTorch——从入门到精通(6.2)自动微分机制
  • vue有了响应式,为何还要diff
  • 3. 轴指令(omron 机器自动化控制器)——>MC_Stop
  • python 实现一个简单的window 任务管理器
  • 【深入理解 SpringBoot3】第一弹:SpringBoot3 快速入门
  • MATLAB+Arduino利用板上的按键控制板上Led灯
  • Ant Design Vue Select 选择器 全选 功能
  • 茅台1935今年动销达到预期,暂无赴港上市计划!茅台业绩会回应多个热点
  • 云南一男子持刀致邻居3死1重伤案二审开庭,未当庭宣判
  • 湛江霞山通报渔船火灾:起火船舶共8艘,无人员伤亡或被困
  • 金俊峰已跨区任上海金山区委副书记
  • 人民日报整版聚焦:专家学者看2025中国经济增长点
  • “影像上海”中的自媒体影像特展:无论何时,影像都需要空间