与链表有关的算法题

文章目录

  • [0. 注意](#0. 注意)
  • [1. 排队顺序(链表的打印)](#1. 排队顺序(链表的打印))
  • [2. 排队顺序(单链表)](#2. 排队顺序(单链表))
  • [3. 队列安排(双向链表)](#3. 队列安排(双向链表))
  • [4. 约瑟夫问题(循环链表)](#4. 约瑟夫问题(循环链表))

0. 注意

new 和 delete 是非常耗时的操作,

在算法比赛中,一般不会使用 new 和 delete 去模拟实现一个链表。

而 STL 里面的 list 的底层就是动态实现的双向循环链表,增删会涉及 new 和 delete,效率不高,竞赛中一般不会使用,而是以静态实现的方式。

关于链表的静态实现 可以参考我写的博客 点击转跳

1. 排队顺序(链表的打印)

https://www.luogu.com.cn/problem/B3630#ide

本题相当于告诉了我们每一个点的后继,使用静态链表的存储方式能够很好的还原这个队列。数组中 [1,n] 的下标可以当做数据域,根据题意修改指针域即可。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

int n,h,i;
const int N=1e6+10;

int main()
{
    cin>>n;
    int ne[N];
    for(i=1;i<=n;i++)
    {
        cin>>ne[i];
    }
    cin>>h;
    for(i=h; i;i=ne[i])
    {
        cout<< i <<" ";
    }
    return 0;
}

2. 排队顺序(单链表)

https://www.luogu.com.cn/problem/B3631

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

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

int h, id;
const int N=1e6+10;
int e[N],ne[N],mp[N],q,op,x,y;


int main()
{
    id++;
    e[id]=1;
    ne[h]=1;
    mp[1]=id;
    cin>>q;
    for(int i=0;i<q;i++)
    {
        cin>>op>>x;
        if(op==1)
        {
            cin>>y;
            id++;
            e[id]=y;
            ne[id]=ne[mp[x]];
            ne[mp[x]]=id;
            mp[y]=id;
        }
        if(op==2)
        {     
            cout<<e[ne[mp[x]]]<<endl;
        }
        if(op==3)
        {
            if(ne[mp[x]])
            {
               // mp[e[ne[mp[x]]]]=0;
                ne[mp[x]]=ne[ne[mp[x]]];
            }
        }
    }
    return 0;
}

3. 队列安排(双向链表)

https://www.luogu.com.cn/problem/P1160

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

循环双链表的静态实现可以参考我的博客 点击转跳

cpp 复制代码
#include<bits/stdc++.h>

using namespace std;

const int N =1e5+10;

int h,id,k,p,M,x;

int ne[N],mp[N],pre[N];

int main()
{
    int num;
    ne[0]=1;
    pre[1]=0;
    mp[1]=1;
    id++;
    cin>>num;
    for(int i=2;i<=num ;i++)
    {
        cin>>k>>p;
        id++;
        mp[i]=id;
        if(p==1)
        {
           ne[id]=ne[k];
           pre[id]=mp[k];
           pre[ne[mp[k]]]=id;
           ne[mp[k]]=id; 
            
        }
        else
        {
           ne[id]=mp[k];
           pre[id]=pre[mp[k]];
           ne[pre[mp[k]]]=id;
           pre[mp[k]]=id ;
        }
    }
    
    cin>>M;
    while(M--)
    {
        cin>>x;
        if(mp[x])
        {

            ne[pre[mp[x]]]=ne[mp[x]];
            pre[ne[mp[x]]]=pre[mp[x]];
            mp[x]=0;
        }
    }

    for(int j = ne[h];j;j=ne[j])
    {
        cout<<j<<" ";
    }
    return 0;
}

4. 约瑟夫问题(循环链表)

https://www.luogu.com.cn/problem/P1996

使⽤循环链表模拟即可! 但是这里面有一些小细节 我们删除元素的时候 每走m-1次就删除后面的元素 (比如给的测试样例是每走3次删一个元素,我们每数2次就删除它后面的元素),这是因为单链表删除有个关键的步骤是 ne[删除元素的前一个元素的位置]=ne[ne[删除前一个元素的位置]]如果我们直接删除当前元素,就很难找到当前元素的前一个位置!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N =110;
int n,m;
int h,id;
int ne[N];

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

    //用t指针进程模拟
    int t=n;//从1开始报数,那么t初始位置就该在最后
    while(n--)
    {
        for(int i=1;i<m;i++)
        {
            t=ne[t];
        }
        cout<<ne[t]<<" ";
        ne[t]=ne[ne[t]];
    }
    return 0;
}
相关推荐
吃好睡好便好5 小时前
在Matlab中绘制横直方图
开发语言·学习·算法·matlab
仰泳之鹅5 小时前
【C语言】自定义数据类型2——联合体与枚举
c语言·开发语言·算法
x_yeyue8 小时前
三角形数
笔记·算法·数论·组合数学
Mr. zhihao8 小时前
深入解析redis基本数据结构
数据结构·数据库·redis
念何架构之路9 小时前
Go语言加密算法
数据结构·算法·哈希算法
AI科技星9 小时前
《数学公理体系·第三部·数术几何》(2026 年版)
c语言·开发语言·线性代数·算法·矩阵·量子计算·agi
失去的青春---夕阳下的奔跑9 小时前
560. 和为 K 的子数组
数据结构·算法·leetcode
黎阳之光9 小时前
黎阳之光:以视频孪生重构智慧医院信息化,打造高标项目核心竞争力
大数据·人工智能·物联网·算法·数字孪生
丷丩10 小时前
三级缓存下MVT地图瓦片服务性能优化策略
算法·缓存·性能优化·gis·geoai-up
m0_6294947310 小时前
LeetCode 热题 100-----25.回文链表
数据结构·算法·leetcode·链表