单链表---移除链表元素
对于无头单向不循环链表,给出头结点head与数值val,删除链表中数据值=val的所有结点
#define ListNodeDataType val
struct ListNode
{ struct ListNode* psll;ListNodeDataType val;
}
方法一---遍历删除
移除所有数值为val的链表结点,那么我们就需要遍历寻找val值为val的结点,然后由于需要删除,因此还需要前一个结点来链接删除结点的后一个结点。
我们创建prev与cur指针,cur指针用于遍历寻找存储数值为val的结点,prev指针用于链接下一个结点。
struct ListNode* prev = NULL;struct ListNode* cur = head;
优先讨论一般情况,当cur->val与val相等时,说明我们需要删除cur指向的结点,那么我们需要先将prev指向结点中存储的next指针指向待删除结点的下一个结点cur->next,即prev->next=cur->next,然后再释放cur指向结点。由于释放完我们需要将cur指向后一个结点,如果首结点val相等,删除首结点,那么如果不创建新指针指向后一个结点我们无法完成cur指向修改操作。
如果cur->val与val不相等,那么我们就将prev与cur指针一前一后向后移动即可。
while(cur!=NULL){if(cur->val==val){struct ListNode* next = cur->next;if(prev)prev->next = next;elsehead = cur->next;free(cur);cur = next;}else{prev = cur;cur=cur->next;}}return head;
如果prev为NULL,那就说明首结点是待删除结点,那么我们需要更改head指向,不能再使用prev->next!这是个空指针的非法访问。
整体代码如下:
struct ListNode* removeElements(struct ListNode* head, int val)
{struct ListNode* prev = NULL;struct ListNode* cur = head;while (cur != NULL){if (cur->val == val){struct ListNode* next = cur->next;free(cur);if (prev)prev->next = next;elsehead = next;cur = next;}else{prev = cur;cur = cur->next;}}return head;
}
方法二---拿出不需要删除的结点放入新的链表
那么我们需要创建一个新的头指针anotherhead,然后需要有一个指针变量cur2来遍历插入结点。
struct ListNode* cur1 = head;struct ListNode* cur2 = NULL;struct ListNode* anotherhead = NULL;
我们通过cur1指针遍历原链表,拿出不需要删除的结点,如果是第一个不删除的结点那么就让anotherhead与cur2均指向该结点,后面就动cur2即可,anotherhead就能够保证不为NULL,指向第一个不删除的结点空间。对于第一个不删除的结点,转换为if条件就是cur2==NULL或者anotherhead==NULL,当两者仍然是NULL,而循环中进入了cur1->val != val的if表达式,那么就需要对头指针another和cur2两者进行赋值。cur1遍历到val值的结点就释放并记录下一个结点位置。
while (cur1){if (cur1->val != val){if (cur2 == NULL){anotherhead = cur1;cur2 = cur1;}else{cur2->next = cur1;cur2 = cur2->next;}cur1 = cur1->next;}else{struct ListNode* prev = cur1;cur1 = cur1->next;free(prev);prev = NULL;}}
但是循环结束并没有完成这个删除操作,因为最后cur2指向的结点中的next指针的指向没有修改。也就是尾结点存储的next指针不一定为NULL,我们需要在循环结束后将cur2->next置空。同时,考虑周全,如果给你的是一个空链表,cur2->next岂不是非法访问?因此还要进行一次if的条件判断,cur2不为空时才将尾结点的next指针置空,最后返回anotherhead或者把anotherhead赋给head返回head。
if (cur2 != NULL)cur2->next = NULL;return anotherhead;
方法三---创建哨兵位头结点newhead
struct ListNode* newhead = (struct ListNode*)malloc(sizeof(struct ListNode));struct ListNode* cur2 = newhead;
开辟一个哨兵位的空间,好处是最后不用使用条件判断cur2是否为NULL,因为cur2最不济也指向哨兵位,不可能出现空指针的解引用操作;当然坏处是,最后由于要释放空间需要额外创建指针存放newhead->next地址,释放newhead空间,再返回我们的首结点地址。
大体与方法二其实差不多。
struct ListNode* removeElements(struct ListNode* head, int val)
{struct ListNode* cur1 = head;struct ListNode* newhead = (struct ListNode*)malloc(sizeof(struct ListNode));struct ListNode* cur2 = newhead;while (cur1){if (cur1->val != val){cur2->next = cur1;cur2 = cur2->next;cur1 = cur1->next;}else{struct ListNode* prev = cur1;cur1 = cur1->next;free(prev);prev = NULL;}}cur2->next = NULL;//下面释放开辟的哨兵位空间struct ListNode* tmp = newhead;newhead = newhead->next;free(tmp);tmp = NULL;return newhead;
}
相关文章:
单链表---移除链表元素
对于无头单向不循环链表,给出头结点head与数值val,删除链表中数据值val的所有结点 #define ListNodeDataType val struct ListNode { struct ListNode* psll;ListNodeDataType val; } 方法一---遍历删除 移除所有数值为val的链表结点,…...
认识redis 及 Ubuntu安装redis
文章目录 一. redis概念二. redis应用场景二. redis的特性四. 使用Ubuntu安装redis 一. redis概念 redis 是在内存中存储数据的中间件, 用在分布式系统 redis是客户端服务器结构的程序, 客户端服务器之间通过网络来通信 二. redis应用场景 redis可用作数据库 类似MySQL, 但…...
Java开发网络安全常见问题
1、敏感信息明文传输 用户敏感信息如手机号、银行卡号、验证码等涉及个人隐私的敏感信息不通过任何加密直接明文传输。 如下图中小红书APP 的手机短信验证码登录接口,此处没有对用户手机号和验证码等信息进行加密传输,可以很简单的截取并开展一些合法的…...
C#基础之委托,事件
文章目录 1 委托1.1 简介1.2 操作使用1.2.1 声明委托(Delegate)1.2.2 实例化委托(Delegate)1.2.3 直接调用和invoke1.2.4 Invoke 和 BeginInvoke 1.3 委托的多播1.4 委托的匿名和lambda1.4.1 匿名方法1.4.2 lambda 表达式 1.5 内置…...
nginx配置静态资源的访问
比如静态资源图片位于/mnt/software/nginx/html/static/images目录下,那么nginx.conf中的配置则为: # 静态文件目录 location /static/images/ { root /mnt/software/nginx/html; try_files $uri $uri/ 404; #找不到时提示404 …...
JS的魔法三角:constructor、prototype与__proto__
在JavaScript中,constructor、prototype和__proto__是与对象创建和继承机制紧密相关的三个概念。理解它们之间的关系对于掌握JavaScript的面向对象编程至关重要。下面将详细介绍这个魔法三角: 1. constructor 定义:constructor是一个函数&am…...
CA系统(file.h---申请认证的处理)
#pragma once #ifndef FILEMANAGER_H #define FILEMANAGER_H #include <string> namespace F_ile {// 读取文件,返回文件内容bool readFilename(const std::string& filePath);bool readFilePubilcpath(const std::string& filePath);bool getNameFro…...
matlab显示sin二维图
1,新建脚本 2、保存脚本 3、脚本命令:clc 清除 脚本命令的信息 clrear all 清除全部 4工作区内容:变量啥的 x0:0.001:2*pi%% 开始 精度 中值 ysin(x) y1cos(x) figure%%产生一个屏幕 plot(x,y)%%打印坐标 title(ysin(x))%%标题 xlabel(…...
验证 kubelet 服务已经停止并且不再生成错误日志
要验证 kubelet 服务已经停止并且不再生成错误日志,可以按照以下步骤进行操作: 1. 检查 kubelet 服务状态 首先,确认 kubelet 服务已经停止。 Bash 深色版本 sudo systemctl status kubelet 你应该看到类似以下的输出,表示服…...
【Linux】进程控制-----进程替换
目录 一、为什么要进行进程替换: 二、进程替换的原理: 三、exec家族: 1、execl: 2、execlp: 3、execv: 4、execvp: 5、execle和execve 编辑 putenv: 一、为什么要进行进程…...
安装SQL Server 2022提示需要Microsoft .NET Framework 4.7.2 或更高版本
安装SQL Server 2022提示需要Microsoft .NET Framework 4.7.2 或更高版本。 原因是:当前操作系统版本为Windows Server 2016 Standard版本,其自带的Microsoft .NET Framework 版本为4.6太低,不满足要求。 根据报错的提示,点击链接…...
使用ECharts创建带百分比标注的环形图
在数据可视化领域,环形图是一种非常有效的图表类型,它能够清晰地展示各部分与整体的关系。今天,我们将通过ECharts来创建一个带百分比标注的环形图,并详细解释如何实现这一效果。 1. 数据准备 首先,我们定义了一些基础…...
学习threejs,设置envMap环境贴图创建反光效果
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.CubeTextureLoader 立…...
go语言里的mkdir mkdirall有什么区别?
在Go语言中,os.Mkdir 和 os.MkdirAll 都是用来创建目录的函数,但它们之间存在一些关键的区别。 ### os.Mkdir - **功能**:os.Mkdir 用于创建一个单一的目录。如果该目录已经存在,则会返回一个错误。 - **参数**: - na…...
使用Python OpenCV实现图像形状检测
目录 一、环境准备 二、读取和预处理图像 读取图像 灰度化 滤波去噪 三、边缘检测 四、查找轮廓 五、绘制轮廓 六、形状分类 七、显示结果 八、完整代码示例 九、总结 图像形状检测是计算机视觉领域中的一项关键技术,广泛应用于工业自动化、机器人视觉、医学图像处…...
继上一篇,设置弹框次数以及自适应图片弹框,部分机型(vivo)老手机不显示的问题
上一篇写的本来测试好多型号都无事, 今天下午公司的战斗机vivo横空冒出… 晕 弹框直接显示都出不来了,现在还有用这种老的机型的,但是没办法咯~ 前端遇到这种兼容性的问题就要勇于解决 主要解决了这几点: // 添加图片加载事件 <imgv-if"imageUrl":src"image…...
基于RISC-V 的代理内核实验(使用ub虚拟机安装基本环境)
1.安装支撑软件 第一步,安装依赖库 RISC-V交叉编译器的执行仍然需要一些本地支撑软件包,可使用以下命令安装: $ sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bis…...
【MMKV】HarmonyOS中的优秀轻量化存储方式
MMKV 引言 在移动应用开发的世界里,数据存储和管理是至关重要的一环。随着技术的不断进步,开发者们对于高性能、轻量级、易用的数据存储解决方案的需求日益增长。MMKV(Memory Mapped Key-Value)正是这样一个开源的高性能key-val…...
docker安装hadoop环境
一、使用docker搭建基础镜像 1、拉取centos系统镜像 # 我这里使用centos7为例子 docker pull centos:7 2、创建一个dockerfiler文件,用来构建自定义一个有ssh功能的centos镜像 # 基础镜像 FROM centos:7 # 作者 #MAINTAINER hadoop ADD Centos-7.repo /etc/yum.re…...
开源多媒体处理工具ffmpeg是什么?如何安装?使用ffmpeg将M3U8格式转换为MP4
目录 一、FFmpeg是什么二、安装FFmpeg(windows)三、将M3U8格式转换为MP4格式 一、FFmpeg是什么 FFmpeg是一款非常强大的开源多媒体处理工具,它几乎可以处理所有类型的视频、音频、字幕以及相关的元数据。 FFmpeg的主要用途包括但不限于&…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...
linux设备重启后时间与网络时间不同步怎么解决?
linux设备重启后时间与网络时间不同步怎么解决? 设备只要一重启,时间又错了/偏了,明明刚刚对时还是对的! 这在物联网、嵌入式开发环境特别常见,尤其是开发板、树莓派、rk3588 这类设备。 解决方法: 加硬件…...
