08-单链表-单链表基本操作2

embedded/2025/3/18 10:27:22/

题目

来源

18. 链表的基本操作

思路

与上一份的最大区别就是要先判断一下要处理的k是否是合法的,也就是要先将指针能够指向k;

上一份的idx是一个全局的指针,由于链表天生就是物理位置不用连续,所以idx可以在任意位置,只要该节点能够和整个链表连接起来就行;

掌握数组模拟链表的基本用法,其他详见代码。

  1. init 函数:初始化链表,将头指针 head 置为 -1,表示链表为空,同时将节点索引 idx 置为 0。
  2. add2head 函数:将元素插入到链表头部,更新节点信息和头指针。
  3. add2k 函数:在指定索引 k 后插入元素 x,更新节点的后继关系。
  4. del2k 函数:删除指定索引 k 后的节点,跳过该节点更新后继关系。
  5. display 函数:遍历链表并输出元素,如果链表为空则输出相应提示。
  6. get2k 函数:遍历链表找到第 k 个元素并输出,若未找到则输出 "get fail"
  7. getIndex 函数:遍历链表找到第 k 个节点的索引,若未找到则返回 -1。
  8. main 函数
    • 读取输入的元素个数 n 并初始化链表,将元素倒序插入到链表头部。
    • 读取操作次数 m,根据不同操作类型执行相应操作,并输出操作结果。

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int head, e[N], ne[N], idx;// 初始化链表
void init() {head = -1;idx = 0;
}// 插入到链表头部
void add2head(int x) {e[idx] = x;ne[idx] = head;head = idx;idx++;
}// 在指定索引 k 后插入元素 x
void add2k(int k, int x) {e[idx] = x;ne[idx] = ne[k];ne[k] = idx;idx++;
}// 删除指定索引 k 后的节点
void del2k(int k) {ne[k] = ne[ne[k]];
}// 显示链表元素
void display() {if (head == -1) {cout << "Link list is empty" << endl;} else {for (int i = head; i != -1; i = ne[i]) {cout << e[i] << " ";}cout << endl;}
}// 获取第 k 个元素
void get2k(int k) {int cnt = 0;for (int i = head; i != -1; i = ne[i]) {cnt++;if (cnt == k) {cout << e[i] << endl;return;}}cout << "get fail" << endl;
}// 获取第 k 个节点的索引
int getIndex(int k) {int cnt = 0;int cur = head;while (cur != -1) {cnt++;if (cnt == k) {return cur;}cur = ne[cur];}return -1;
}int main() {int n;cin >> n;init();// 倒序插入元素到链表头部for (int i = 0; i < n; i++) {int x;cin >> x;add2head(x);}int m;string op;cin >> m;while (m--) {cin >> op;if (op == "show") {display();} else if (op == "delete") {int k;cin >> k;if (k == 1) { //相当于从头结点插入if (head != -1) {head = ne[head];cout << "delete OK" << endl;} else {cout << "delete fail" << endl;}} else {int preIndex = getIndex(k - 1); //取第k个指针是否存在if (preIndex != -1) { //需要有得删,简单来说就是K要存在del2k(preIndex);cout << "delete OK" << endl;} else {cout << "delete fail" << endl;}}} else if (op == "insert") {int k, x;cin >> k >> x;if (k == 1) {add2head(x);cout << "insert OK" << endl;} else {int preIndex = getIndex(k - 1);if (preIndex != -1) { //k存在add2k(preIndex, x);cout << "insert OK" << endl;} else {cout << "insert fail" << endl;}}} else if (op == "get") {int k;cin >> k;get2k(k);}}return 0;
}

http://www.ppmy.cn/embedded/173567.html

相关文章

使用OpenCV和MediaPipe库——抽烟检测(姿态监控)

目录 抽烟检测的运用 1. 安全监控 (1) 公共场所禁烟监管 (2) 工业安全 2. 智能城市与执法 (1) 城市违章吸烟检测 (2) 无人值守管理 3. 健康管理与医疗 (1) 吸烟习惯分析 (2) 远程监护 4. AI 监控与商业分析 (1) 保险行业 (2) 商场营销 5. 技术实现 (1) 计算机视…

微服务即时通信系统---(八)用户管理子服务

本章节,主要对项目中用户管理子服务模块进行分析、开发与测试。 功能设计 用户管理子服务,主要用于管理用户的数据,以及关于用户信息的各项操作,因此,在本模块中,用户管理子服务需要提供以下的功能性接口 用户注册用户输入 用户名(昵称) + 用户密码 进行注册。用户登录…

docker学习

基本结构 镜像(image)&#xff1a; docker镜像可以当作一个模板&#xff0c;通过这个模板可以创建多个容器。 例如一个tomcat镜像>运行>容器(提供服务) 容器(container)&#xff1a; docker利用容器技术&#xff0c;可以独立运行一个或一组应用(容器间相互隔离) docker…

C语言:编程设计猜数游戏

先由计算机想一个数给用户猜&#xff0c;如果猜对了&#xff0c;提示“right&#xff01;”&#xff0c;猜错了&#xff0c;提示“wrong&#xff01;及大小” 思路&#xff1a;用随机函数rand&#xff08;&#xff09;取到计算机想的数 代码&#xff1a; #include <stdio.…

JVM、MySQL常见面试题(尽力局)

JVM篇 一.谈一谈JDK、JRE、JVM分别是什么&#xff0c;有什么联系&#xff1f; 1.JDK是Java工具包&#xff0c;里面包含了JRE、Javac编译器等。 2.JRE是java运行环境&#xff0c;里面包含了JVM、JavaSE标准库类等。 3.JVM是Java虚拟机&#xff0c;运行编译后的.class的文件&am…

C/C++中应用程序调用其他dll模块,想要使用vs调试这个dll里的代码,附加进程的方式无法命中断点,但通过调试启动的方式却可以,是什么原因?

文章目录 1. 符号文件&#xff08;PDB&#xff09;未正确加载2. DLL 版本与调试代码不一致3. DLL 加载时机错过调试器附加4. 调试器类型不匹配5. 编译优化导致断点偏移6. 断点位置未被执行7. 配置属性设置错误快速诊断流程&#xff1a;终极方案&#xff1a;直接调试启动 在 Vis…

机器学习中说的正向传递和反向传递是什么意思

在机器学习&#xff0c;尤其是深度学习领域&#xff0c;​正向传递&#xff08;Forward Pass&#xff09;​和反向传递&#xff08;Backward Pass&#xff09;​是神经网络训练过程中的两个核心步骤。它们共同构成了训练神经网络的基础框架&#xff0c;通常与梯度下降算法结合使…

提高开发效率:公共字段自动化填充方案

目录 问题描述 解决方案 Mybatis-Plus AOP注解 方案比较 MyBatis-Plus 自动填充功能 AOP 注解 问题描述 当我们在开发过程中&#xff0c;处理像创建时间、创建人等这样的公共字段会显得比较繁琐&#xff0c;尤其是在每个实体都需要这些信息的情况下。就比如&#xff0c…