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

news2025/1/9 1:57:20

链表的基础操作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.coloradmin.cn/o/1275226.html

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

相关文章

有IP没有域名可以申请证书吗?

一、IP证书是什么&#xff1f; ip证书是用于公网ip地址的SSL证书&#xff0c;与我们通常所讲的SSL证书并无本质上的区别&#xff0c;但由于SSL证书通常颁发给域名&#xff0c;而组织机构需要公共ip地址的SSL证书&#xff0c;这类SSL证书就是我们所说的ip证书。ip证书具有安全、…

C++ 学习 之 类的初始化与逗号运算符的联动

我们来看一个代码 class A { public:A(int x) {cout << "123" << endl;}A(int x, int y) {cout << "456" << endl;}}a (1, 2); int main() {} 这个代码的输出结果是什么&#xff1f; 答案是 123 因为编译器把 ( 1 , 2 ) 识别…

mysql区分大小写吗

mysql在windows下默认是不区分大小写的&#xff0c;在linux下默认是区分大小写的。 所以&#xff0c;为了避免出问题&#xff0c;许多公司的数据库编程规范中明确规定&#xff1a;库名、表名、列名、索引名一律小写&#xff0c;不同单词之间以下划线分割&#xff0c;且控制在3…

Python+Requests模块添加cookie

请求中添加cookies 对于某些网站&#xff0c;登录然后从浏览器中获取cookies&#xff0c;以后就可以直接拿着cookie登录了&#xff0c;无需输入用户 名密码。 一、在参数中添加cookie 在发送请求时使用cookies 代码示例&#xff1a; import requests # 1&#xff0c;在参数…

如何选择 Facebook 代理?

Facebook上从事业务推广、广告或资料推广以及群组的用户需要高质量且可靠的代理。使用代理&#xff0c;用户可以在账号被封锁的情况下访问自己的资料&#xff0c;同时与多人进行即时通信&#xff0c;并能够&#xff1a; 自动发送邀请参加各种活动&#xff1b; 通过特殊的机器人…

Java流处理之序列化和打印流

文章目录 序列化概述ObjectOutputStream类构造方法序列化操作 ObjectInputStream类构造方法反序列化操作1**反序列化操作2** 案例&#xff1a;序列化集合案例分析案例实现 打印流概述PrintStream类构造方法改变打印流向 序列化 概述 Java 提供了一种对象序列化的机制。用一个…

无人巡检 | AIRIOT变电站无人机运防一体管理解决方案

传统的变电站安全管理存在着人力成本高、效率低、安全风险难以全面控制等问题&#xff0c;主要依靠人工巡检和监控设备&#xff0c;往往存在如下的运维问题和管理痛点&#xff1a; 巡检监控能力差&#xff1a;传统变电站管理系统无法对变电站进行全面的巡检监控&#xff0c;以…

使用Xshell启动远程服务器上的tensorboard:本地浏览器打开

在远程服务器上启动的tensorboard产生的localhost网址用本地浏览器一般不能直接打开&#xff0c;我们需要建立本地PC与远程服务器的通信&#xff0c;将tensorboard的映射端口与本地端口连接起来&#xff08;参考解决方案&#xff09;。 一、连接远程服务器设置 二、添加SSH隧道…

SSM项目实战-service实现

1、SysUserService.java package com.atguigu.schedule.service;import com.atguigu.schedule.pojo.SysUser;public interface SysUserService {SysUser getSysUser(SysUser sysUser); }2、SysUserServiceImpl.java package com.atguigu.schedule.service.impl; import com.atg…

7nm项目之顶层规划——01数据导入

1.创建workspace 创建workspace后&#xff0c;在其目录下产生。 CORTEXA53.json文件是将有默认配置的文件master.json、有library的.config.json文件、tunes下CORTEXA53.tunes.json文件合并 注&#xff1a;tunes下的CORTEXA53.tunes.json文件可以覆盖一些master.json的设置…

Vue+Element-ui实例_在form中动态校验tag标签

1.开发需求 在日常开发中&#xff0c;我们会遇到form表单的动态添加和校验&#xff0c;当我们需要在动态添加的内容中再次动态使用输入框的时候&#xff0c;就会变得很繁琐&#xff0c;我在网上找了很多案例&#xff0c;没有符合自己需求的内容&#xff0c;只好闲暇时间自己搞…

Unity UGUI控件之Horizontal Layout Group

Horizontal Layout Group是Unity中的UGUI控件&#xff0c;用于在水平方向上对子对象进行布局。 主要有一下作用&#xff1a; 水平布局&#xff1a;Horizontal Layout Group将子对象按照水平方向进行布局&#xff0c;可以控制子对象的排列顺序和间距。自动调整尺寸&#xff1a…

MOS管的静电击穿问题

MOS管输入电阻很高&#xff0c;为什么一遇到静电就不行了&#xff1f; 静电击穿&#xff1a;由于静电的积累导致电压超过了原本MOS的绝缘能力&#xff0c;导致电流突然增大的现象。 MOS管基础知识了解&#xff1a; G极(gate)—栅极&#xff0c;不用说比较好认 S极(source)—源…

Mybatis相关API(Sqlsession和sqlsessionFactroy)

代码 private static SqlSessionFactory sqlSessionFactory;static { ​try { // 获得核心配置文件String resource "mybits-config.xml"; // 加载核心配置文件InputStream inputStream Resources.getResourceAsStream(resource…

一种excel多线程并发写sheet的方案

一、背景 有一次项目的需求要求导出excel&#xff0c;并且将不同的数据分别写到不同的sheet中。 二、 方案概述 首先一开始使用easyexcel去导出excel&#xff0c;结果发现导出时间需要3秒左右。于是想着能不能缩短excel导出时间&#xff0c;于是第一次尝试使用异步线程去查询数…

weblogic任意文件上传漏洞(CVE-2018-2894)

任务一&#xff1a; 复现环境中的漏洞 任务二&#xff1a; 上传webshell或者反弹shell&#xff0c;并执行whoami。 任务一&#xff1a; 1.环境搭建&#xff0c;发现需要密码&#xff0c;所以我们去日志里面查看管理员密码。 2.了解一下这个平台&#xff0c;然后进行一些基本配…

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

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

金蝶云星空单据界面新增状态,操作明细行的新增按钮时判断表头基础资料是否必录

文章目录 金蝶云星空单据界面新增状态&#xff0c;操作明细行的新增按钮时判断表头基础资料是否必录BOS配置代码实现 金蝶云星空单据界面新增状态&#xff0c;操作明细行的新增按钮时判断表头基础资料是否必录 BOS配置 四种方式都不生效。 代码实现 表单插件的BeforeDoOpera…

最短路算法

文章目录 最短路总览朴素Dijkstra - 稠密图 - O ( n 2 ) O(n^2) O(n2)具体思路时间复杂度分析使用场景AcWing 849. Dijkstra求最短路 ICODE 堆优化 D i j k s t r a Dijkstra Dijkstra 算法 - 稀疏图 - O ( m l o g n ) O(mlogn) O(mlogn)具体思路和时间复杂度分析使用场景A…

九章量子计算机:引领量子计算的新篇章

九章量子计算机:引领量子计算的新篇章 一、引言 随着科技的飞速发展,量子计算已成为全球科研领域的前沿议题。九章量子计算机作为中国自主研发的量子计算机,具有划时代的意义。本文将深入探讨九章量子计算机的原理、技术特点、应用前景等方面,带领读者领略量子计算的魅力…