卡码网15 .链表的基本操作III

链表的基础操作III

时间限制:1.000S  空间限制:128MB

题目描述

请编写一个程序,实现以下链表操作:构建一个单向链表,链表中包含一组整数数据。 

1. 实现在链表的第 n 个位置插入一个元素,输出整个链表的所有元素。
2. 实现删除链表的第 m 个位置的元素,输出整个链表的所有元素。 

要求: 

1. 使用自定义的链表数据结构。
2. 提供一个 linkedList 类来管理链表,包含构建链表、插入元素、删除元素和输出链表元素的方法。
3. 在 main 函数中,创建一个包含一组整数数据的链表,然后根据输入的 n 和 m,调用链表的方法插入和删除元素,并输出整个链表的所有元素。

输入描述

每次输出只有一组测试数据。 

每组的第一行包含一个整数 k,表示需要构建的链表的长度。

第二行包含 k 个整数,表示链表中的元素。 

第三行包含一个整数 S,表示后续会有 S 行输入,每行两个整数,第一个整数为 n,第二个整数为 x ,代表在链表的第 n 个位置插入 x。 

S 行输入... 

在 S 行输入后,后续会输入一个整数 L,表示后续会有 L 行输入,每行一个整数 m,代表删除链表中的第 m 个元素。 

L 行输入...

输出描述

包含多组输出。 

每组第一行输出构建的链表,链表元素中用空格隔开,最后一个元素后没有空格。

然后是 S 行输出,每次插入一个元素之后都将链表输出一次,元素之间用空格隔开,最后一个元素后没有空格;

如果插入位置不合法,则输出“Insertion position is invalid.”。 

然后是 L 行输出,每次删除一个元素之后都将链表输出一次,元素之间用空格隔开,最后一个元素后没有空格; 

如果删除位置不合法,则输出“Deletion position is invalid.”。

输入示例
5
1 2 3 4 5
3
4 3
3 4
9 8
2
1
0
输出示例
1 2 3 3 4 5
1 2 4 3 3 4 5
Insertion position is invalid.
2 4 3 3 4 5
Deletion position is invalid.

 

之前我们也提到过,往数组的中间插入一个元素,后续所有元素都需要往后挪动一位,而链表则不必这么麻烦,那往链表的中间添加或者删除一个节点具体应该怎么做呢?

插入链表的过程

image-20230912120144709

我们可以假设这样一个场景:在传递情报过程中,A的下线是B, 也就是A -> next = B, 现在我们要引入一个C充当A和B之间的中间人,A的下线是C, C的下线是B,我们可以直接将A的next指向C,即A -> next = C, 然后将C的next指向B, 但是B无法直接表示,之前是用A -> next来表示B的,现在A -> next已经指向C了,所以在操作之前,我们需要实现定义一个变量保存B,假设为tmp, 然后将C的next指针指向B即可。

在链表中,具体插入的过程如下:

  • 找到要插入的位置的前一个节点,将之命名为cur, 要插入的位置的下一个节点,将之命名为tmp, 它们之间的关系是cur -> next = tmp
  • 创建一个新的链表newNode, 将curnext指针指向newNode, 即cur -> next = nowNode
  • newNodenext指针指向tmp, 即newNode -> next = tmp

这样就完成了链表节点的插入过程。转换成代码如下:

// 创建了一个新的 ListNode 结构的节点,值为x, 并将其地址赋给指针 newNode
ListNode *newNode = new ListNode(x);
// 创建了一个名为 tmp 的指针,临时存储当前节点 cur 的下一个节点的地址。
ListNode *tmp = cur ->next;
// 将当前节点 cur 的 next 指针更新为指向新节点 newNode,将新节点插入到当前节点后面。
cur->next = newNode;
// 将新节点 newNode 的 next 指针设置为指向之前临时存储的节点 tmp
newNode->next = tmp;

删除链表的过程

image-20230912115756421

删除链表的过程则比较简单,只需要找到删除节点的前一个节点cur, 并将其next 指针设置为指向当前节点的下下个节点,从而跳过了下一个节点,实现了节点的删除操作。

// cur->next 表示当前节点 cur 的下一个节点
// cur->next->next 表示要删除的节点的下一个节点
// 当前节点 cur 的 next 指针不再指向要删除的节点,而是指向了要删除节点的下一个节点
cur->next = cur->next->next;

打印链表

在函数内部,定义了一个名为 cur 的指针,它初始化为指向 head,即链表的头节点。

什么时候链表迭代到最后一个节点呢?检查当前节点 cur 的下一个节点是否存在(不为 NULL), 当前节点的下一个节点为NULL时说明下一个节点为空节点,即链表的末尾。

while(cur -> next != NULL) {}

在循环体内,打印当前节点 cur 的下一个节点(cur->next)的值(val)。接下来,将 cur 更新为指向链表中的下一个节点,以便在下一次循环中打印下一个节点的值。

while (cur->next != NULL) {cout << cur->next->val << " ";cur = cur -> next;
}

循环体结束时,表示已经遍历完了整个链表。最后打印一个换行符,用于分隔不同的输出行。

// 打印链表
void printLinklist(ListNode* head) {ListNode* cur = head;while (cur->next != NULL) {cout << cur->next->val << " ";cur = cur -> next;}cout << endl;
}

代码编写

我们照例,先把代码的基础结构以及定义链表的结构体写出来。

#include <iostream>
using namespace std;
struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(nullptr) {}
};
int main() {}

首先,需要接收整数k, 表示需要构建链表的长度

int main() {int k, val; // k表示链表长度,val表示构建链表时输入的值cin >> k;
}

然后我们需要构建一个长度为k的链表,在构建链表之前,可以先创建一个虚拟头节点以及初始化一个指针cur指向虚拟头节点,方便后续节点的接入。

ListNode* dummyHead = new ListNode(0); // 创建了一个虚拟头结点
ListNode* cur = dummyHead; // 定义一个指向当前节点的指针 cur,初始指向虚拟头结点
for (int i = 0; i < k; i++) { // 或者使用while(n--)cin >> val;ListNode *newNode = new ListNode(val); // 构造一个新的节点cur -> next = newNode; // 将新节点接入链表cur = cur -> next;      // cur 指向下一个节点
}

之后,需要接收一个整数s表示s行输入,每行两个整数,第一个整数为 n,第二个整数为 x ,代表在链表的第 n 个位置插入 x。

int s, n, x; // s表示s行输入,n代表插入位置,x代表插入元素的值
cin >> s; // 输入s
while (s--) {cin >> n >> x; // 输入n和x}

题目中要求,插入位置不合法时,输出"Insertion position is invalid."

什么时候才会插入位置不合法呢,当插入的位置n是一个小于等于0的数或者n大于链表的长度时,插入位置不合法。

⚠️ 需要注意,插入后链表的长度会变化,所以我们可以提前定义一个变量listLen指代链表的长度

int listLen = k; // 定义链表的长度
if (n <= 0 || n > listLen) { // 当要插入的位置非法时cout << "Insertion position is invalid." << endl; // 输出错误提示continue;
}

如果不满足上面的if语句,说明插入的位置合法,后续执行的操作是完成插入以及打印链表。

插入链表节点的过程在前面已经描述过,只需找到需要插入位置的前一个节点即可, 也就是第n-1个节点,从虚拟头节点开始遍历,需要走n-1

// 指针重新指向虚拟头结点,准备用cur遍历链表
cur = dummyHead;
// 寻找添加节点的位置,i从1开始,
for (int i = 1; i < n; i++) {cur = cur->next;
}

插入节点的代码直接拿来使用即可,不要忘记将链表长度加1

// 插入节点
ListNode *newNode = new ListNode(x); // 构造一个新的节点
ListNode *tmp = cur ->next;
cur->next = newNode;
newNode->next = tmp;// 链表长度加1
listLen++;

接着完成打印链表即可

// 打印链表
printLinklist(dummyHead);

链表节点删除的前置步骤类型,需要接收一个整数 L,表示后续会有 L 行输入,每行一个整数 m,代表删除链表中的第 m 个元素。

int l,m;
cin >> l;
while (l--) {cin >> m;
}

判断是否是非法输入

if (m <= 0 || m > listLen) {cout << "Deletion position is invalid." << endl;continue;
}

找到要删除节点的前一个节点

// 指针重新指向虚拟头结点,准备用cur遍历链表
cur = dummyHead;//开始寻找删除节点的位置,i从1开始,因为节点计数从1开始
for (int i = 1; i < m; i++) cur = cur->next;
// 删除节点
cur->next = cur->next->next;
listLen--; // 链表长度减一
// 如果删除节点后链表为空则不打印
if (listLen != 0) printLinklist(dummyHead);

 c++代码实现:

#include<iostream>
using namespace std;
typedef struct ListNode{int data;ListNode *next;ListNode(int x):data(x),next(nullptr){}
}*L;
void printLinkList(ListNode *dummyHead){ListNode *cur=dummyHead;while(cur->next!=NULL){cout<<cur->next->data<<" ";cur=cur->next;}cout<<endl;
}
int main(){int k;L dummyHead=new  ListNode(0);//创建一个虚拟头节点cin>>k;int listlen=k;//记录链表的长度L cur=dummyHead;//定义一个指向当前节点的指针cur,初始指向虚拟头节点int val;for(int i=0;i<k;i++){cin>>val;L newNode=new ListNode(val);cur->next=newNode;cur=cur->next;}int s,n,x;cin>>s;while(s--){cin>>n>>x;if(n<=0||n>listlen){cout << "Insertion position is invalid." << endl;continue;}//指针重新指向虚拟头节点。准备用cur遍历链表cur=dummyHead;//for(int i=1;i<n;i++)cur=cur->next;L newNode=new ListNode(x);L tmp=cur->next;cur->next=newNode;newNode->next=tmp;listlen++;printLinkList(dummyHead);}int l,m;cin>>l;while(l--){cin>>m;if(m<=0||m>listlen){cout << "Deletion position is invalid." << endl;continue;}cur=dummyHead;for(int i=1;i<m;i++) cur=cur->next;cur->next=cur->next->next;listlen--;if(listlen!=0){printLinkList(dummyHead);}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

0-1背包问题详解

0-1背包问题 部分一&#xff1a;问题描述 0-1背包问题是一类经典的组合优化问题&#xff0c;它出现在很多实际生活和工业环境中。问题描述如下&#xff1a; 假设你是一个冒险家&#xff0c;带着一个可承重的背包&#xff0c;面对一堆宝物。每件宝物都有自己的价值&#xff0…

【设计模式-2.1】创建型——单例模式

说明&#xff1a;设计模式根据用途分为创建型、结构性和行为型。创建型模式主要用于描述如何创建对象&#xff0c;本文介绍创建型中的单例模式。 饿汉式单例 单例模式是比较常见的一种设计模式&#xff0c;旨在确保对象的唯一性&#xff0c;什么时候去使用这个对象都是同一个…

Rust UI开发(一):使用iced构建UI时,如何在界面显示中文字符

注&#xff1a;此文适合于对rust有一些了解的朋友 iced是一个跨平台的GUI库&#xff0c;用于为rust语言程序构建UI界面。 iced的基本逻辑是&#xff1a; UI交互产生消息message&#xff0c;message传递给后台的update&#xff0c;在这个函数中编写逻辑&#xff0c;然后通过…

Pytest做性能测试?

Pytest其实也是可以做性能测试或者基准测试的。是非常方便的。 可以考虑使用Pytest-benchmark类库进行。 安装pytest-benchmark 首先&#xff0c;确保已经安装了pytest和pytest-benchmark插件。可以使用以下命令安装插件&#xff1a; pip install pytest pytest-benchmark …

黑马一站制造数仓实战1

1. 项目目标 一站制造 企业中项目开发的落地&#xff1a;代码开发 代码开发&#xff1a;SQL【DSL SQL】 SparkCore SparkSQL 数仓的一些实际应用&#xff1a;分层体系、建模实现 2. 内容目标 项目业务介绍&#xff1a;背景、需求 项目技术架构&#xff1a;选型、架构 项目环境…

ubuntu系统下搭建本地物联网mqtt服务器的步骤

那么假如我们需要做一些终端设备&#xff0c;例如温湿度传感器、光照等物联网采集设备要接入呢&#xff1f;怎么样才能将数据报送到服务器呢&#xff1f; 以下内容基于我们ubuntu系统下的emqx成功启动的基础上。我们可以用浏览器键入控制板的地址&#xff0c;如果启动成功&…

数据爬取+可视化实战_告白气球_词云展示----酷狗音乐

一、前言 歌词上做文本分析&#xff0c;数据存储在网页上&#xff0c;需要爬取数据下来&#xff0c;词云展示在工作中也变得日益重要&#xff0c;接下来将数据爬虫与可视化结合起来&#xff0c;做个词云展示案例。 二、代码 # -*- coding:utf-8 -*- # 酷狗音乐 通过获取每首歌…

HarmonyOS到底有哪些独特之处?你真正了解鸿蒙多少!

鸿蒙系统太炸裂了&#x1f4a5;我已经后悔了&#x1f62d;后悔没早点学习鸿蒙 HarmonyOS 概念&#xff0c;系统定位 1&#xff1a;鸿蒙系统是由华为公司自主研发的全球化开放源代码操作系统&#xff0c;它具有以下特别之处&#xff1a; 2&#xff1a;分布式架构&#xff1a;…

SpringBoot+mysql+vue实现大学生健康档案管理系统前后端分离

一、项目简介 本项目是一套基于SpringBoot实现大学生健康档案管理系统&#xff0c;主要针对计算机相关专业的正在做bishe的学生和需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目可以直接作为bishe使用。 项目都经过严格调试&#…

数据结构——图解链表OJ题目

学完了单链表之后&#xff0c;我们对其基本结构已经有了一定的了解&#xff0c;接下来我们通过一些题目强化对链表的理解&#xff0c;同时学习一些面试笔试题目的新思路以及加强对数据结构单链表的掌握。 目录 题目一.876. 链表的中间结点 - 力扣&#xff08;LeetCode&#x…

14.Tomcat和HTTP协议-[一篇通]

文章目录 1.HTTP 协议1.1HTTP 是什么1.2理解 "应用层协议"1.3理解 HTTP 协议的工作过程1.4HTTP 协议格式1.4.1抓包工具的使用(Fiddler)1.4.2抓包工具的原理1.4.3抓包结果1.4.4协议格式总结 1.5HTTP 请求 (Request)1.5.1认识 URL1.5.1.1URL 基本格式1.5.1.2关于 URL e…

二次元检测设备导轨修复指南

二次元检测设备是一种高精度的测量仪器&#xff0c;用于检测物体表面的形状、尺寸和精度等。直线导轨是二次元检测设备中最重要的组成部分之一&#xff0c;它的精度和稳定性直接影响到设备的测量结果和可靠性&#xff0c;因此&#xff0c;对导轨进行修复和保养是非常重要的。 直…

网站实现验证码功能

一、验证码 一般来说&#xff0c;网站在登录的时候会生成一个验证码来验证是否是人类还是爬虫&#xff0c;还有一个好处是防止恶意人士对密码进行爆破。 二、流程图 三、详细说明 3.1 后端生成验证码 Override public Result<Map<String, String>> getVerifica…

Linux安装nginx超完整步骤

1、到官网&#xff08;http://nginx.org&#xff09;下载nginx包,推荐使用稳定版本 2、上传nginx到linux系统&#xff0c;我上传的默认路径在/usr/local/下 3、安装依赖环境&#xff1a; ①安装gcc环境 yum install gcc-c ②安装PCRE库&#xff0c;用于解析正则表达式 yum…

MinkowskiEngine安装

pip install torch ninjagit clone https://github.com/NVIDIA/MinkowskiEngine.git cd MinkowskiEngine安装之前先把并行安装的thread数降低&#xff0c;否则会导致进程卡死。 打开setup.py文件内位于142行的MAX_COMPILATION_THREADS变量值从12改成4。 export CXXg-7 python…

深入理解Zookeeper系列-1.初识Zoookeeper

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理&#x1f525;如果感觉博主的文章还不错的话&#xff…

办公软件PDF转换工具 - Bruce的PDF工具pdftool

Bruce的PDF工具 - 办公软件PDF转换工具 - pdftool&#xff0c;支持&#xff1a; 1、图片转PDF&#xff0c;支持图片自动压缩&#xff0c;可预览图片 2、合并PDF&#xff0c;支持多个PDF合并成一个PDF 3、PDF转图片&#xff0c;PDF的每页转成一张图片 4、OFD转PDF&#xff0c;O…

操作系统进程与线程篇

目录 一、进程 1.1、进程状态 1.2、进程的控制结构 1.3、进程的控制 1.4、进程的上下文切换 二、线程 2.1.线程是什么 2.2、线程与进程的比较 2.3、线程的上下文切换 2.4、线程的实现 2.5、轻量级线程 三、进程间的通信方式 3.1、管道 3.2、消息队列 3.3、共享内…

手摸手Element-ui路由VueRoute

后端WebAPI准备 https://router.vuejs.org/zh/guide/ https://v3.router.vuejs.org/zh/installation.html 路由 <template> <el-table :data"tableData" style"width: 100%" :row-class-name"tableRowClassName"…

国产linux单用户模式破解无密码登陆 (麒麟系统用户登录密码遗忘解决办法)

笔者手里有一批国产linu系统&#xff0c;目前开始用在日常的工作生产环境中&#xff0c;我这个老程序猿勉为其难的充当运维的或网管的角色。 国产linux系统常见的为麒麟Linux&#xff0c;统信UOS等&#xff0c;基本都是基于debian再开发的linux。 问题描述&#xff1a; 因为…