91.【C语言】数据结构之单向链表的头删和尾删

目录

1.尾删函数SLTPopBack

代码示例(写入SList.c)

在SList.h中写入该函数的声明

main.c部分代码改为

​编辑

分析

解决方法

方法1:双指针算法(快指针tail,慢指针pretail)

方法2

2.头删函数SLTPopFront

一个节点示意图

多个节点示意图

代码示例(写入SList.c)

在SList.h中写入该函数的声明

main.c部分代码改为


承接87.【C语言】数据结构之链表的头插和尾插文章

1.尾删函数SLTPopBack

代码示例(写入SList.c)

void SLTPopBack(SLTNode** pphead)
{SLTNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}free(tail);tail = NULL;
}

在SList.h中写入该函数的声明

main.c部分代码改为

void TestSList1()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPopBack(&plist);SLTPrint(plist);
}

运行后出了问题

分析

虽然为tail使用free函数并将tail置NULL,但是tail前面的节点含的指针并没有置NULL,导致其为野指针,因而出现了-572662307这样的随机值

解决方法

找到tail前的节点含的指针,并将其置NULL

方法1:双指针算法(快指针tail,慢指针pretail)

void SLTPopBack(SLTNode** pphead)
{SLTNode* pretail = NULL;//初始化慢指针SLTNode* tail = *pphead;while (tail->next != NULL){	pretail = tail;//待tail指针内容改变前,先赋值给慢指针tail = tail->next;}pretail->next = NULL;//tail的前一个节点含的指针置NULLfree(tail);tail = NULL;
}

方法2

void SLTPopBack(SLTNode** pphead)
{SLTNode* tail = *pphead;while (tail->next->next != NULL){	tail = tail->next;}free(tail->next);tail->next = NULL;
}

tail->next->next != NULL//跨了一个节点

看起来没有问题,但是将main.c部分代码改成

void TestSList1()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);
}

 就会出问题

当链表为1->NULL时,tail->next->next != NULL会导致读取访问权限冲突(原因:tail->next为NULL,NULL->next不合法)

如果用方法1,也会出现同样的问题

因此要在尾删函数的一开始做出判断:1.是否为空链表? 2.链表是否只有一个节点?

修正后的代码

void SLTPopBack(SLTNode** pphead)
{assert(pphead);assert(*pphead);//检查是否为空链表,空链表不可以尾删//检查链表是否只有一个节点if ((*pphead)->next == NULL){free(*pphead);//*pphead就是plist*pphead = NULL;}else{SLTNode* tail = *pphead;while (tail->next->next != NULL){tail = tail->next;}free(tail->next);tail->next = NULL;}
}

注意断言的顺序:先断言pphead,再断言*pphead!

 

2.头删函数SLTPopFront

和尾删函数一样:一开始做出判断:1.是否为空链表? 2.链表是否只有一个节点?

空链表不可头删,直接断言

一个节点示意图

多个节点示意图

一个节点和多个节点的处理方式可以合并在一起

代码示例(写入SList.c)

void SLTPopFront(SLTNode** pphead)
{assert(pphead);assert(*pphead);//检查是否为空链表SLTNode* first = *pphead;*pphead = first->next;first = NULL;
}

注意断言的顺序:先断言pphead,再断言*pphead!  

在SList.h中写入该函数的声明

main.c部分代码改为

void TestSList1()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPrint(plist);SLTPopFront(&plist);SLTPrint(plist);SLTPopFront(&plist);SLTPrint(plist);SLTPopFront(&plist);SLTPrint(plist);SLTPopFront(&plist);SLTPrint(plist);
}

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

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

相关文章

DEVOPS: 集群伸缩原理

概述 阿里云 K8S 集群的一个重要特性,是集群的节点可以动态的增加或减少有了这个特性,集群才能在计算资源不足的情况下扩容新的节点,同时也可以在资源利用 率降低的时候,释放节点以节省费用理解实现原理,在遇到问题的…

华为OD机试 - 无向图染色(Java 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(E卷D卷A卷B卷C卷)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加…

云智慧完成华为原生鸿蒙系统的适配, 透视宝 APM 为用户体验保驾护航

2024 年 10 月 22 日,首个国产移动操作系统 —— 华为原生鸿蒙操作系统 HarmonyOS NEXT 正式面世,成为继 iOS 和 Android 后的全球第三大移动操作系统。HarmonyOS NEXT,从系统内核、数据库根基,到编程语言创新、AI(人工…

无人机之任务分配算法篇

无人机的任务分配算法是无人机系统中的重要组成部分,它决定了无人机如何高效、合理地执行各种任务。以下是一些常见的无人机任务分配算法: 一、合同网协议(Contract Net Protocol, CNP) 基本概念:CNP算法是一种分布式…

【WRF数据处理】基于GIS4WRF插件将geotiff数据转为tiff(geogrid,WPS所需数据)

【WRF数据处理】基于GIS4WRF插件将geotiff数据转为tiff(geogrid,WPS所需数据) 数据准备:以叶面积指数LAI为例QGis实操:基于GIS4WRF插件将geotiff数据转为tiff警告:GIS4WRF: Input layer had an unexpected …

【MySQL基础】高级查询

文章目录 一、聚合函数:COUNT、SUM、AVG、MIN、MAX1. 统计总数:COUNT2. 计算总和:SUM3. 计算平均值:AVG4. 找最小值:MIN5. 找最大值:MAX 综合使用聚合函数的例子小结 二、分组查询——GROUP BY 和 HAVING1.…

ElasticSearch备考 -- Index shrink

一、题目 索引task包括5个分片一个副本,对索引执行shrink压缩操作,压缩后索引为1主分片,索引名称为task-new 二、思考 在执行shrink前必须满足三个前置条件 The index must be read-only.A copy of every shard in the index must reside o…

名词(术语)了解--CSSOM (CSS Object Model)

名词(术语)了解–CSSOM (CSS Object Model) CSSOM 概述 CSSOM 是一个与 DOM (Document Object Model) 相对应的、用于 CSS 的 API 集合。 它提供了一种程序化的方式来读取和修改文档的样式信息。 CSSOM 的主要组成部分 样式规则树 document └── …

智能化超声波影像分析,优化医疗决策的开源AI解决方案

思通数科的医疗信息精准抽取系统是一款基于人工智能的开源软件,旨在自动化处理医疗数据,特别是从超声波影像到诊断报告的信息提取。该系统集成了图像识别、自然语言处理和知识图谱等先进技术,能够从医疗影像中提取关键数据,并将这…

Objective-C 音频爬虫:实时接收数据的 didReceiveData_ 方法

在互联网技术领域,数据的获取和处理是至关重要的。尤其是对于音频内容的获取,实时性和效率是衡量一个爬虫性能的重要指标。本文将深入探讨在Objective-C中实现音频爬虫时,如何高效地使用didReceiveData:方法来实时接收数据,并通过…

Python轴承故障诊断 (15)基于CNN-Transformer的一维故障信号识别模型

往期精彩内容: Python-凯斯西储大学(CWRU)轴承数据解读与分类处理 Pytorch-LSTM轴承故障一维信号分类(一)-CSDN博客 Pytorch-CNN轴承故障一维信号分类(二)-CSDN博客 Pytorch-Transformer轴承故障一维信号分类(三)-CSDN博客 三十多个开源…

如何在 Elasticsearch Ruby 客户端中使用 ES|QL Helper

作者:来自 Elastic Fernando Briano 了解如何使用 Elasticsearch Ruby 客户端编写 ES|QL 查询并处理其结果。 简介 Elasticsearch Ruby 客户端可用于编写 EQ|QL 查询,使处理从 esql.query 返回的数据更加容易。ES|QL 允许开发人员通过查询过滤、转换和分…

【elkb】ELKB安装token过期

问题 elastic启动时候生成的token 有效期只有30分钟。 30分钟后提示: Couldnt configure Elastic Generate a new enrollment token or configure manually. 相关版本信息 elasticsearch:8.8.1kibana:8.8.1logstash:8.8.1file…

交易所开发:开启数字金融新时代

当今数字化高速发展的时代,交易所作为金融市场的核心枢纽,发挥着至关重要的作用。而随着区块链技术的兴起,数字货币交易所的开发更是为金融领域带来了全新的变革与机遇。 一、数字货币交易所的重要性 数字货币交易所是连接数字货币世界与传统…

企业内训|LLM大模型在服务器和IT网络运维中的应用-某日企IT运维部门

本课程是为某在华日资企业集团的IT运维部门专门定制开发的企业培训课程,本课程旨在深入探讨大型语言模型(LLM)在服务器及IT网络运维中的应用,结合当前技术趋势与行业需求,帮助学员掌握LLM如何为运维工作赋能。通过系统…

网上商城设计小程序ssm+论文源码调试讲解

2相关技术 2.1微信小程序 小程序是一种新的开放能力,开发者可以快速地开发一个小程序。小程序可以在微信内被便捷地获取和传播,同时具有出色的使用体验。尤其拥抱微信生态圈,让微信小程序更加的如虎添翼,发展迅猛。 2.2 MYSQL数据…

大贤3D家谱——让修家谱不再困难

修家谱作为一种文化传统,承载着家族的历史和文化记忆,但近年来确实面临一些困难,导致很多人不愿意修家谱。以下是一些主要原因: 1、信息获取难度: 家谱的修订需要大量的历史资料和族谱记录。许多家庭的老谱由于时间久…

Node + HTML搭建自己的ChatGPT [基础版]

文章目录 明明外面的ChatGPT产品那么多了,为什么要在本地搭建自己的ChatGPT呢?整体架构流程1. 获取APIKey1.1 常见的AI模型1.2 为什么选DeepSeek1.3 怎么获取DeepSeek的APIKey1.3.1 注册并登录DeepSeek开放平台1.3.2 选择API keys1.3.3 创建API key1.3.4…

【Linux学习】(8)第一个Linux编程进度条程序|git三板斧

前言 第一个Linux编程——进度条git的简单使用 一、第一个Linux编程——进度条 在写进度条之前我们需要两个基础知识: 回车换行缓冲区 1. 回车换行 首先我们需要知道回车换行它是两个概念,回车是回车,换行是换行换行:光标从上往下…

DEVOPS: 认证与调度

概述 不知道大家有没有意识到一个现实,就是大部分时候,我们已经不像以前一样通过命令行,或者可视窗口来使用一个系统了现在我们上微博、或者网购,操作的其实不是眼前这台设备,而是一个又一个集群 通常,这样…