卡码网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.mzph.cn/news/188862.shtml

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

相关文章

软著项目推荐 深度学习实现语义分割算法系统 - 机器视觉

文章目录 1 前言2 概念介绍2.1 什么是图像语义分割 3 条件随机场的深度学习模型3\. 1 多尺度特征融合 4 语义分割开发过程4.1 建立4.2 下载CamVid数据集4.3 加载CamVid图像4.4 加载CamVid像素标签图像 5 PyTorch 实现语义分割5.1 数据集准备5.2 训练基准模型5.3 损失函数5.4 归…

计算机软件的分类

以功能进行分类&#xff0c;计算机软件通常可以分为系统软件和应用软件两大类。 系统软件&#xff1a;系统软件是计算机运行和管理的基本软件&#xff0c;包括操作系统、驱动程序、系统工具和服务程序等。操作系统是系统软件的核心&#xff0c;负责管理计算机的硬件资源、提供用…

python之pyqt专栏10-键盘事件

需求 通过按键盘的上下左右&#xff0c;移动button的位置。 UI界面设计 代码 # 导入sys模块 import sysfrom PyQt6.QtCore import Qt # PyQt6.QtWidgets模块中导入QApplication, QWidget from PyQt6.QtWidgets import QApplication, QWidget# untitled模块中导入Ui_Form类 f…

跨越鸿沟-颠覆性产品营销指南笔记

跨越鸿沟-颠覆性产品营销指南笔记 一、发现鸿沟 一、技术采用生命周期 技术采用生命周期 如果采用一个新产品&#xff0c;我们就得改变一贯的行为模式&#xff0c;或者改变我们依赖的其他产品或服务&#xff0c;那么&#xff0c;我们对技术采用的态度就变得很重要&#xff0c…

shell编程系列(8)-使用sed处理文本

文章目录 引言sed用法详解在文本中定位打印文本替换文本删除文本新增文本 结语 引言 在日常工作学习中我们都会遇到要编辑文本的场景&#xff0c;例如我们要用vim或者nano等命令去编辑代码&#xff0c;处理文本文件等&#xff0c;这些命令的特点都是需要我们进行交互式的实时处…

使用visual Studio MFC 平台实现对灰度图添加椒盐噪声,并进行均值滤波与中值滤波

平滑处理–滤波 本文使用visual Studio MFC 平台实现对灰度图添加椒盐噪声&#xff0c;并进行均值滤波与中值滤波 关于其他MFC单文档工程可参考 01-Visual Studio 使用MFC 单文档工程绘制单一颜色直线和绘制渐变颜色的直线 02-visual Studio MFC 绘制单一颜色三角形、渐变颜色边…

Visual Studio通过ClaudiaIDE插件设置背景图片

首先&#xff0c;在VS菜单栏上选择扩展-管理扩展&#xff0c;搜索插件为 ClaudiaIDE&#xff0c; 下载完成之后&#xff0c;关闭VS&#xff0c;点击Modify按钮安装&#xff1a; 等待安装完成&#xff0c;进入 VS , 打开 工具----选项---- ClauDiaIDE 界面 这个是背景色调 我选的…

2023-12-01 AndroidR 系统在root目录下新建文件夹和创建链接,编译的时候需要修改sepolicy权限

一、想在android 系统的根目录下新建一个tmp 文件夹&#xff0c;建立一个链接usr链接到data目录。 二、在system/core/rootdir/Android.mk里面的LOCAL_POST_INSTALL_CMD 增加 dev proc sys system data data_mirror odm oem acct config storage mnt apex debug_ramdisk tmp …

共享单车停放(简单的struct结构运用)

本来不想写这题的&#xff0c;但是想想最近沉迷玩雨世界&#xff0c;班长又问我这题&#xff0c;就草草写了一下 代码如下&#xff1a; #include<stdio.h> #include<math.h> struct parking{int distance;int remain;int speed;int time;int jud; }parking[50]; …

2021年11月10日 Go生态洞察:Twelve Years of Go

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

前端:实现div的隐藏与显示

效果 完整代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-widt…

2021年12月14日 Go生态洞察:Go 1.18 Beta 1 发布与泛型的引入

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

C语言:求十个数中的平均数

分析&#xff1a; 程序中定义了一个average函数&#xff0c;用于计算分数的平均值。该函数接受一个包含10个分数的数组作为参数&#xff0c;并返回平均值。在主函数main中&#xff0c;首先提示输入10个分数&#xff0c;然后使用循环读取输入的分数&#xff0c;并将它们存储在名…

【BEV感知 LSS方案】Lift-Splat-Shoot(LSS)

前言 LSS全称是Lift-Splat-Shoot&#xff0c;它先从车辆周围的多个摄像头拍摄到的图像进行特征提取&#xff0c;在特征图中估计出每个点的深度&#xff0c;然后把这些点“提升”到3D空间中。 接着&#xff0c;这些3D信息被放置到一个网格上&#xff0c;最后将这些信息“拍扁”…

OSI七层模型与TCP/IP四层模型

一、OSI七层模型简述 OSI 模型的七层是什么&#xff1f;在 OSI 模型中如何进行通信&#xff1f;OSI 模型有哪些替代方案&#xff1f; TCP/IP 模型关于专有协议和模型的说明 二、七层模型详解&#xff08;DNS、CDN、OSI&#xff09; 状态码DNS nslookup命令 CDN whois命令 …

Java中的异常你了解多少?

目录 一.认识异常二.异常分类三.异常的分类1.编译时异常2.运行时异常 四.异常的处理1.LYBL&#xff1a;事前防御型2.EAFP&#xff1a;事后认错型 五.异常的抛出Throw注意事项 六.异常的捕获1.异常的捕获2.异常声明throws3.try-catch捕获并处理 七.自定义异常 一.认识异常 在Jav…

Python实现FA萤火虫优化算法优化BP神经网络分类模型(BP神经网络分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 萤火虫算法&#xff08;Fire-fly algorithm&#xff0c;FA&#xff09;由剑桥大学Yang于2009年提出 , …

ChatGPT探索:提示工程详解—程序员效率提升必备技能【文末送书】

文章目录 一.人工智能-ChatGPT1.1 ChatGPT简介1.2 ChatGPT探索&#xff1a;提示工程详解1.2 提示工程的优势 二.提示工程探索2.1 提示工程实例&#xff1a;2.2 英语学习助手2.3 Active-Prompt思维链&#xff08;CoT&#xff09;方法2.4 提示工程总结 三.文末推荐与福利3.1《Cha…

这几款 idea 插件让效率起飞!

作者&#xff1a;苍何&#xff0c;前大厂高级 Java 工程师&#xff0c;阿里云专家博主&#xff0c;CSDN 2023 年 实力新星&#xff0c;土木转码&#xff0c;现任部门技术 leader&#xff0c;专注于互联网技术分享&#xff0c;职场经验分享。 &#x1f525;热门文章推荐&#xf…

【CAD二次开发】标注箭头,获取修改标注箭头图块

常见的的标注箭头有以下种类 public static List<string> ArrowBlock = new List<string>(){" ","_CLOSEDBLANK&