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

数据结构 单链表 数组模仿链表

数组模仿链表

因为普通的链表,每次新增,要重新创建变量,时间复杂度太高

所以我们算法题中可以用数组模拟链表

单链表

邻接表分为存储图,存储树

常见单链表

head->[val,next]->[val,next]->[val,next]->.....->null

使用数组模拟时

e[N]代表节点上的值,ne[N]代表next指针,实际上就是指向下一个值的数组下标

伪代码示例,[值,数组下标],->代表指针指向的值

链表:

head->[a,0]->[b,1]->[c,2]->[d,3]->null

此链表用数组模拟,e[N]和ne[N]就是

e[0]=a,e[1]=b,e[2]=c,e[3]=d
ne[0]=1,ne[1]=2,ne[2]=3,ne[3]=-1(-1表示链表结束)

初始变量

int head;//头

int e[N];//节点上的值

int ne[N];//next,指向下一个节点的值,实际上存储的就是下一个节点在e[N]中的数组下标

int idx;//int idx;//表示数组存储到的下标位置+1,也就是未用的数组索引(下标)

初始化

void init()
{
    head = -1;//初始化头执行结束
    idx = 0;//idx全部可以用
}

头结点后面添加元素:

假设我们有以下链表结构:

head -> [a, 0] -> [b, 1] -> [c, 2] -> [d, 3] -> null

对应的数组表示为:

e  = [a, b, c, d]
ne = [1, 2, 3, -1]

执行在头结点后添加元素的函数

void add_to_head(int x)
{
    e[idx] = x;//在e数组后面的未用位置,新放入了一个数
    ne[idx] = head;//ne[idx]指向head指向下标位置,现在相当于ne[idx]和head都指向原链表第一个节点
    //head的值,对应的下标也更新为现在的idx,通过head的值可快速找到e[idx],ne[idx]
    //抽象来说,就是本来指向原链表第一个节点的head,现在重新指向ne[idx]
    head = idx;//也就是e[head],ne[head]
    idx++;//维持idx是未用数组下标
}

链表结构变成如下

head -> [e, 5]-> [a, 0] -> [b, 1] -> [c, 2] -> [d, 3] -> null

对应数组

e  = [a, b, c, d, e]
ne = [1, 2, 3, -1, 0]

在索引 k 后插入一个数

假设我们有以下链表结构:

head -> [a, 0] -> [b, 1] -> [c, 2] -> [d, 3] -> null

对应的数组表示为:

e  = [a, b, c, d]
ne = [1, 2, 3, -1]

执行在索引 k 后插入一个数的函数

void add(int k, int x)
{
    e[idx] = x;//将X值加入数组
    ne[idx] = ne[k];//复制e[k]的指针指向的下一个节点,现在ne[idx],ne[k]都指向e[ne[k]]
    ne[k] = idx;//ne[k]更新,变成指向新加入的节点,e[idx]
    idx++;维持idx是未用数组下标
}

假设k是1,x是e,idx为4

链表结构变成如下

head -> [a, 0] -> [b, 1] -> [e, 4] -> [c, 2] -> [d, 3] -> null

对应数组

e  = [a, b, c, d, e]
ne = [1, 4, 3,-1, 2]

流程

删索引为 k 的元素的下一个

这个最简单,直接把ne[k]指向的节点e[ne[k]],变成ne[k]指向的下下个节点

e[ne[k]]是下一个节点,他的下一个节点指向的下标,就是ne[ne[k]]

所以,删除k节点函数如下

void remove(int k)
{
    ne[k] = ne[ne[k]];//ne[k]指向他的下一个节点指向的下标索引
}

典型例题

实现一个单链表,链表初始为空,支持三种操作:

  1. 向链表头插入一个数;
  2. 删除第 k 个插入的数后面的一个数;
  3. 在第 k 个插入的数后插入一个数。

现在要对该链表进行 M 次操作,进行完所有操作后,从头到尾输出整个链表。

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

输入格式

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

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

  1. H x,表示向链表头插入一个数 x。
  2. D k,表示删除第 k 个插入的数后面的数(当 k为 0 时,表示删除头结点)。
  3. I k x,表示在第 k个插入的数后面插入一个数 x(此操作中 k 均大于 0)。
输出格式

共一行,将整个链表从头到尾输出。

数据范围

1≤M≤100000
所有操作保证合法。

输入样例:
10
H 9
I 1 1
D 1
D 0
H 6
I 3 6
I 4 5
I 4 5
I 3 4
D 6
输出样例:
6 4 6 5

代码实现

#include<iostream>
using namespace std;
const int N = 100010;
int e[N];int ne[N];
int idx;int head;
void init(){
    head = -1;
    idx = 0;
}
void add_head(int x){
    e[idx]=x;
    ne[idx]=head;
    head=idx;
    idx++;
}
void add(int x,int k){
    e[idx]=x;
    ne[idx]=ne[k];
    ne[k]=idx;
    idx++;
}
void remove(int k){
    ne[k]=ne[ne[k]];
}
int main(){
    int m;char c;int x,k;
    cin>>m;
    init();
    while(m--){
        cin>>c;
        if(c=='H'){
            cin>>x;
            add_head(x);
        }
        else if(c=='D'){
            cin>>k;
        if(!k) head = ne[head];//题目中说,在k=0时,意思是删除头结点,0-1为负数下标,特判
        else remove(k-1);//第k个插入的数的数组下标索引,为k-1
        }
        else {
            cin>>k>>x;
            add(x,k-1);//第k个插入的数的数组下标索引,为k-1
        }
    }
    for(int i=head;i!=-1;i=ne[i]){
        cout<<e[i]<<" ";
    }
    
    return 0;
}

相关文章:

  • 【Java/数据结构】二叉树(BinaryTree)
  • ipconfig、ping、ipconfig/all 4个常用 **Windows终端(CMD)命令** 的详细解释
  • vscode 通过Remote-ssh远程连接服务器报错 could not establish connection to ubuntu
  • 基于ssm人脸识别的网络相册管理系统(源码+lw+部署文档+讲解),源码可白嫖!
  • 2-2 MATLAB鮣鱼优化算法ROA优化CNN超参数回归预测
  • 【git】认识git的本地仓库
  • jeecgboot vue 分片上传 minio
  • AOA与TOA混合定位,MATLAB例程,自适应基站数量,三维空间下的运动轨迹,滤波使用EKF
  • Apache Shiro 统一化实现多端登录(PC端移动端)
  • canvas.toDataURL返回 Base64 编码黑色图片的检测方法
  • cs231n-图像分类:kNN与线性分类器
  • 【遥感小目标数据集】【AI-TOD】Tiny Object Detection in Aerial Images
  • Java多线程与JConsole实践:从线程状态到性能优化!!!
  • LeetCode Hot100 刷题笔记(4)—— 二叉树、图论
  • PyTorch实现Transformer模型
  • 输出输入练习
  • 《数字图像处理》第四章 频率域滤波简要学习笔记以及频率域滤波与空间域滤波的区别
  • 构建稳健的机器学习系统:应对数据偏移挑战
  • Leetcode 交错字符串
  • [FPGA基础学习]加法器、三八译码器及DE2-115基本使用方法和数码管显示
  • 纽约市长称墨西哥海军帆船撞桥事故已致2人死亡
  • 荣盛发展:新增未支付债务11.05亿元
  • 音乐节困于流量
  • 泽连斯基与埃尔多安会面,称已决定派遣代表团前往伊斯坦布尔
  • 通用汽车回应进口车业务调整传闻:因经济形势变化重组,致力于在中国持续发展
  • 澎湃·镜相第二届非虚构写作大赛初选入围名单公示