当前位置: 首页 > news >正文

单链表的实现(数据结构)

一. 单链表的实现

我们在上一篇中简单的认识了链表的组成和结构,并打印出链表,那么今天就来具体实现一下单链表对于数据增加、删减、插入等。

接下来就是我们在链表中对于数据的增、删、插的实现,对于我们的链表来说在任何地方增加数据都需要来申请一个新的结点,首先呢,SLDatatype是我们更改int类型的名称之后得来的,SL是结构体的名称,我们先申请一个结构体大小的新结点node,然后再将新结点中的x的值赋给data,再让新结点的next指向NULL,申请新结点的函数写好之后我们就来写关于数据的增、删、插等,所以我们直接先来完成申请新结点的代码:

SLDatatype* SLBuyNode(SLDatatype x)
{SL* node = (SL*)malloc(sizeof(SL));if (node == NULL){perror("malloc fail!");exit(1);}node->data = x;node->next = NULL;return node;
}

 尾插

//尾插函数
void SLPuchBack(SL** pphead, SLDatatype x)
{//申请新结点//*pphead-->&plistSL* newnode = SLBuyNode(x);if (*pphead == NULL){*pphead = newnode;}else{//尾结点-->新结点SL* pcur = *pphead;//找尾结点while (pcur->next){pcur = pcur->next;}pcur->next = newnode;}}
void SLTest01()
{SL* plist = NULL;SLPuchBack(&plist, 1);SLprintf(plist);SLPuchBack(&plist, 2);SLPuchBack(&plist, 3);SLprintf(plist);
}int main()
{SLTest01();return 0;
}

在实现让任何代码之前,我们都因该将思路理清楚,尾插该注意什么,怎么去是实现?首先一定是要找到最后一个结点,pphead是我们的头结点,我们一贯会将pphead赋给一个新的指针pcur,使用while循环找到最后一个结点,但是如果while里面是pcur的那我们不就直接跳出循环,那我们还怎么找最后一个结点呢?所以我们不如使用while(pcur->next),也就是当我们pcur指向3的时候我们的next刚好指向的是NULL,停止了循环,刚好pcur还指向尾结点,然后我们在将newnode赋值给我们的最后一个结点。在上面的代码中我们要注意的一点是SLPuchBack函数中传入的是形参,这个时候我们要使用传值调用,因为如果使用传值调用的话,形参的改变并不影响实参,所以在测试函数SLTest01中传入的是&plist,然而plist本身就是一个指针,所以我们在SLPuchBack中要使用二级指针即**pphead。

 头插:对于头插就简单很多,我们只需要申请一个新的结点,然后将结点与原本的头结点连接,在让pphead指向现在新的结点。

//头插函数
void SLPuchFront(SL** pphead, SLDatatype x)
{assert(pphead);SL* newnode = SLBuyNode(x);newnode->next = *pphead;*pphead = newnode;
}

尾删:对于尾删我们并不能简单的将最后一个结点删除,因为这样会让前面一个指针变成野指针,可以把最后一个结点前面的结点的next指向NULL,然后将最后一个结点释放掉。

//尾删函数
void SLPopBack(SL** pphead)
{assert(pphead && *pphead);//假如原本只有一个结点if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SL* pcur = *pphead;SL* front = NULL;while (pcur->next){front = pcur;pcur = pcur->next;}front->next = NULL;free(pcur);pcur = NULL;}

头删: 

//头删函数
void SLPopFront(SL** pphead)
{assert(pphead && *pphead);SL* pcur = (*pphead)->next;free(*pphead);*pphead = pcur;
}

 在指定位置之前插入数据

void SLInsertFront(SL** pphead, SL* pos, SLDatatype x)
{assert(pphead && pos);SL* newnode = SLBuyNode(x);SL* pcur = *pphead;if (pos == *pphead){newnode->next = pos;*pphead = newnode;}else{while (pcur->next != pos){pcur = pcur->next;}newnode->next = pos;pcur->next = newnode;}}

 在指定位置之后插入数据

void SLInsertAfert(SL* pos, SLDatatype x)
{assert(pos);SL* newnode = SLBuyNode(x);newnode->next = pos->next;pos->next = newnode; 
}

 删除pos结点

void SLErase(SL** pphead, SL* pos)
{assert(pphead && *pphead);assert(pos);SL* pcur = *pphead;if (pos == *pphead){SLPopFront(pphead);}else{while (pcur->next != pos){pcur = pcur->next;}pcur->next = pos->next;free(pos);pos = NULL;}

 删除pos之后的结点

void SLEraseAfert(SL* pos)
{assert(pos&&pos->next);SL* deal = pos->next;pos->next = pos->next->next;free(deal);deal = NULL;
}

 销毁链表

void SLDestroy(SL** pphead)
{SL* pcur = *pphead;while (pcur){SL* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}

上面关于链表的指定位置插入、删除等算法,我们要注意的就是在我们更改链表中的数据的时候,要更改的这个数据会影响其他的数据吗?如果影响我们应该怎么做,提前设置好几个指针变量还是其他的办法,寻找某一个结点的时候while循环的条件是什么,这些我们都要注意,上面已经给出较为详细的代码,大家可以参考,另外就是注意free指针之后一定要将其置为空指针NULL,单链表完成之后我们就要拿一些算法题来练手,如何使用单链表来完成一些算法题。

二. 算法题

移除链表元素

https://leetcode.cn/problems/remove-linked-list-elements/description/

这个题目是移除链表元素,我们有两个思路一个就是利用我们原本的单链表对指定位置的结点进行删除,还有就是创建一个新的链表然后将符合的元素移到新的链表中,我们可以来实现第二中思路: 创建一个新链表,遍历原链表,将不等于给定值  val  的节点依次添加到新链表中。
 
1. 创建新链表的哑节点(dummy node):
- 目的是简化操作,避免处理新链表头节点为空的特殊情况。
- 例如,可以创建一个值为  0  的哑节点,将其  next  指针初始化为  null 。
2. 遍历原链表:
- 从原链表的头节点  head  开始遍历。
- 检查当前节点的值是否等于  val 。
- 如果不等于  val ,则将该节点添加到新链表中。
3. 添加节点到新链表:
- 将原链表中不等于  val  的节点的  next  指针指向新链表的末尾节点的  next 。
- 更新新链表的末尾节点为该节点。
4. 返回新链表的头节点:
 - 新链表的头节点为哑节点的  next 。
 通过以上步骤,就可以使用创建新链表的方法删除原链表中所有值为  val  的节点,并返回新的头节点。

 

#include <stdio.h>
#include <stdlib.h>struct ListNode {int val;struct ListNode* next;
};struct ListNode* createNode(int val) {struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));newNode->val = val;newNode->next = NULL;return newNode;
}struct ListNode* removeElements(struct ListNode* head, int val) {struct ListNode* dummy = createNode(0);struct ListNode* curr = dummy;while (head) {if (head->val!= val) {curr->next = head;curr = curr->next;}head = head->next;}curr->next = NULL;return dummy->next;
}void printList(struct ListNode* head) {while (head) {printf("%d -> ", head->val);head = head->next;}printf("NULL\n");
}void freeList(struct ListNode* head) {struct ListNode* temp;while (head) {temp = head;head = head->next;free(temp);}
}
int main() {// 创建链表 1->2->6->3->4->5->6struct ListNode* head = createNode(1);head->next = createNode(2);head->next->next = createNode(6);head->next->next->next = createNode(3);head->next->next->next->next = createNode(4);head->next->next->next->next->next = createNode(5);head->next->next->next->next->next->next = createNode(6);int val = 6;struct ListNode* newHead = removeElements(head, val);printList(newHead);freeList(newHead);return 0;
}

相关文章:

单链表的实现(数据结构)

一. 单链表的实现 我们在上一篇中简单的认识了链表的组成和结构&#xff0c;并打印出链表&#xff0c;那么今天就来具体实现一下单链表对于数据增加、删减、插入等。 接下来就是我们在链表中对于数据的增、删、插的实现&#xff0c;对于我们的链表来说在任何地方增加数据都需…...

印刷质量检测笔记

一、印刷质量检测的背景与挑战 印刷品的质量检测&#xff0c;特别是针对高精度要求的印刷产品&#xff0c;如包装材料、标签、书籍封面等&#xff0c;一直是制造业中的一个关键环节。印刷品可能存在的质量问题多种多样&#xff0c;包括但不限于颜色偏差、文字模糊、漏印、多印…...

16、论文阅读:Mamba YOLO:用于目标检测的基于 SSM 的 YOLO

Mamba YOLO: SSMs-Based YOLO For Object Detection 总结前言感受野为什么Transformer 的结构被引入&#xff0c;显著扩展了模型的感受野&#xff1f;状态空间模型SSM 介绍相关工作实时目标检测端到端目标检测器视觉状态空间模型 方法预处理整体架构ODSS BlockLocalSpatial Blo…...

python项目实战---使用图形化界面下载音乐

音乐下载 设计思路&#xff1a; 设计界面编写爬虫代码绑定爬虫打包exe文件 这个是最终的设计成果&#xff0c;所有的下载歌曲都在“下载mp3”文件夹里面 完整代码 逻辑代码 import os.path import reimport requests from PyQt5.QtWidgets import QApplication,QWidget,QM…...

无人机干扰与抗干扰,无人机与反制设备的矛与盾

无人机干扰与抗干扰&#xff0c;以及无人机与反制设备之间的关系&#xff0c;可以形象地比喻为矛与盾的较量。以下是对这两方面的详细探讨&#xff1a; 一、无人机干扰与抗干扰 1. 无人机干扰技术 无人机干扰技术是指通过各种手段对无人机系统进行干扰&#xff0c;使其失去正…...

JAVA基础:单元测试;注解;枚举;网络编程 (学习笔记)

单元测试 操作步骤&#xff1a; a.导包import org.junit; b.三个注解 Test Before After c.点击Test 运行就可以了 用在不需要控制台输入的情境下&#xff1a;javaweb&#xff0c;框架项目&#xff0c;微服务项目 供开发人员自己做测试。 package com.page…...

Meta 上周宣布正式开源小型语言模型 MobileLLM 系列

在 7 月发布之后&#xff0c;Meta 上周宣布正式开源能够在智能手机上运行的小型语言模型 MobileLLM 系列。 Meta 在四个月前发布了这两个参数量小于 10 亿的语言模型 MobileLLM 125M 及 MobileLLM 350M。如今&#xff0c;Meta 又开发出了更大参数量的模型版本&#xff0c;包括…...

安全篇(1)判断安全固件

判断安全固件的方法 一、通过串口开机打印 改方法适用Android与Tina 1.开机打印为SBOOT为安全 [289]HELLO! SBOOT is starting! 2.开机打印boot0为非安全 [88]BOOT0 commit : 1cbb5ea8b3 二、通过读数据 1.getprop | grep verifiedbootstate 这条命令的输出表示设备的…...

ArcGIS005:ArcMap常用操作101-150例动图演示

摘要&#xff1a;本文涵盖了GIS软件操作的多方面内容&#xff0c;包括地图文档的新建、打开、保存及版本兼容性处理&#xff1b;错误与警告的查阅及帮助文档的使用技巧&#xff1b;地图打印比例尺的调整与地图信息的完善&#xff1b;图层操作的撤销与恢复&#xff0c;界面元素的…...

如何用ChatGPT结合Python处理遥感数据

在科技飞速发展的时代&#xff0c;遥感数据的精准分析已经成为推动各行业智能决策的关键工具。从无人机监测农田到卫星数据支持气候研究&#xff0c;空天地遥感数据正以前所未有的方式为科研和商业带来深刻变革。然而&#xff0c;对于许多专业人士而言&#xff0c;如何高效地处…...

matlab 质心重合法实现点云配准

目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示1、初始位置2、配准结果本文由CSDN点云侠原创,原文链接,首发于:2024年11月5日。 一、算法原理 1、原理概述 质心重合法是将源点云 P P P...

ubuntu双屏只显示一个屏幕另一个黑屏

简洁的结论&#xff1a; 系统环境 ubuntu22.04 nvidia-535解决方案 删除/etc/X11/xorg.conf 文件 记录一下折腾大半天的问题。 ubuntu系统是22.04,之前使用的时候更新驱动导致桌面崩溃&#xff0c;重新安装桌面安装不上&#xff0c;请IT帮忙&#xff0c;IT一番操作过后也表示…...

小菜家教平台:基于SpringBoot+Vue打造一站式学习管理系统

前言 现在已经学习了很多与Java相关的知识&#xff0c;但是迟迟没有进行一个完整的实践&#xff08;之前这个项目开发到一半&#xff0c;很多东西没学搁置了&#xff0c;同时原先的项目中也有很多的问题&#xff09;&#xff0c;所以现在准备从零开始做一个基于SpringBootVue的…...

网络自动化03:简单解释send_config_set方法并举例

目录 拓扑图设备信息 netmiko涉及方法send_config_set()方法的简单示例代码输出结果代码解释导入模块配置信息config_device_interface_description 函数主程序块总结 send_config_set方法参数&#xff1a;1. enter_config_mode2. config_commands3. enter_config_mode4. error…...

跳表原理笔记

课程地址 跳表是一种基于随机化的有序数据结构&#xff0c;它提出是为了赋予有序单链表以 O(logn) 的快速查找和插入的能力 创建 首先在头部创建一个 sentinel 节点&#xff0c;然后在 L1 层采用“抛硬币”的方式来决定 L0 层的指针是否增长到 L1 层 例如上图中&#xff0c;L…...

计算机毕业设计Hadoop+PySpark深度学习游戏推荐系统 游戏可视化 游戏数据分析 游戏爬虫 Scrapy 机器学习 人工智能 大数据毕设

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

AI开发-三方库-torch-torchvision

1 需求 数据集&#xff1a;torchvision.datasets torchvision.datasets.MNIST数据变换&#xff1a;torchvision.transforms torchvision.transforms.Composetorchvision.transforms.ToTensortorchvision.transforms.Normalize模型&#xff1a;torchvision.models可视化工具&…...

解析 MySQL 数据库容量统计、存储限制与优化技巧

管理 MySQL 数据库时&#xff0c;了解数据库中的数据量和存储占用情况是非常重要的&#xff0c;尤其是在面对大规模数据时。无论是为了优化数据库性能&#xff0c;还是为了进行容量规划&#xff0c;准确地统计数据库的容量可以帮助我们做出更好的决策。mysql的客户端工具是Navi…...

智能工厂的软件设计 思维进阶与数学程序

本文要点 讨论 “智能工厂的软件设计”中的“数学程序”。 这里 “数学程序” 是指能“格物致知”来理解“相续”一词。 完整的表述是&#xff1a; 思想素养提升的 思维进阶法&#xff08;三种 数学程序 &#xff1a; 格物致知 &#xff09;之思维导图&#xff1a; 二叉树及其…...

技术速递|GitHub Copilot upgrade assistant for Java 技术预览发布!

作者&#xff1a;Nick Zhu - Senior Program Manager 排版&#xff1a;Alan Wang 随着人工智能和大型语言模型&#xff08;LLMs&#xff09;的不断发展&#xff0c;Agent&#xff08;“智能代理”&#xff09;和智能代理化工作流程正在迅速成为AI领域的下一个前沿。这些自主系统…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

UE5 音效系统

一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类&#xff0c;将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix&#xff0c;将上述三个类翻入其中&#xff0c;通过它管理每个音乐…...

当下AI智能硬件方案浅谈

背景&#xff1a; 现在大模型出来以后&#xff0c;打破了常规的机械式的对话&#xff0c;人机对话变得更聪明一点。 对话用到的技术主要是实时音视频&#xff0c;简称为RTC。下游硬件厂商一般都不会去自己开发音视频技术&#xff0c;开发自己的大模型。商用方案多见为字节、百…...

MySQL用户远程访问权限设置

mysql相关指令 一. MySQL给用户添加远程访问权限1. 创建或者修改用户权限方法一&#xff1a;创建用户并授予远程访问权限方法二&#xff1a;修改现有用户的访问限制方法三&#xff1a;授予特定数据库的特定权限 2. 修改 MySQL 配置文件3. 安全最佳实践4. 测试远程连接5. 撤销权…...