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

单链表(增删查改)

目录

  • 一、什么是单链表?
  • 二、单链表的增删查改
    • 2.1 结构体变量的声明
    • 2.2 申请新结点
    • 2.2 链表的头插
    • 2.3 链表的尾插
    • 2.4 链表的头删
    • 2.5 链表的尾删
    • 2.6 链表的查找
    • 2.7 链表的任意位置后面插入
    • 2.8 链表的任意位置后面删除
    • 2.9 链表的销毁
    • 2.10 链表的打印
  • 三、代码汇总
    • 3.1 SLish.h
    • 3.2 SLish.c
    • 3.3 test.c

一、什么是单链表?

单链表是一种链式存取的数据结构,,链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。以“结点的序列”表示的线性表称作线性链表(单链表),单链表是链式存取的结构。简单来说单链表就是一个一个的节点链接起来的链式结构,每个节点里面存储着一个数据和与它链接的下一个节点的(指针)地址。(注意,每一个节点都是同一种结构体类型)

二、单链表的增删查改

2.1 结构体变量的声明

typedef int SLTDataType;
typedef struct SLTNode
{SLTDataType data;struct SLTNode* next;}SLTNode;

2.2 申请新结点

SLTNode* BuySListNode(SLTDataType x)
{SLTNode* newNode = (SLTNode*)malloc(sizeof(SLTNode));if (newNode == NULL){perror("malloc fail");return NULL;}else{newNode->data = x;newNode->next = NULL;return newNode;}
}

2.2 链表的头插

void SListPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newNode = BuySListNode(x);newNode->next = *pphead;*pphead = newNode;
}

2.3 链表的尾插

void SListPushBack(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newNode = BuySListNode(x);if (*pphead == NULL){*pphead = newNode;}else{SLTNode* tail = *pphead;while (tail->next){tail = tail->next;}tail->next = newNode;}}

2.4 链表的头删

void SListPopFront(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* del = *pphead;*pphead = (*pphead)->next;free(del);del = NULL;}

2.5 链表的尾删

void SListPopBack(SLTNode** pphead)
{assert(pphead);assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLTNode* tailPrev = NULL;SLTNode* tail = *pphead;while (tail->next){tailPrev = tail;tail = tail->next;}tailPrev->next = NULL;free(tail);tail = NULL;}}

2.6 链表的查找

SLTNode* SListFind(SLTNode* pphead, SLTDataType x)
{SLTNode* cur = pphead;while (cur){if (cur->data == x){return cur;}else{cur = cur->next;}}printf("找不到%d\n",x);return NULL;}

2.7 链表的任意位置后面插入

void SListInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);SLTNode* newNode = BuySListNode(x);SLTNode* posNext = pos->next;pos->next = newNode;newNode->next = posNext;}

2.8 链表的任意位置后面删除

void SListEraseAfter(SLTNode* pos)
{assert(pos && pos->next);SLTNode* posNext = pos->next;pos->next = posNext->next;free(posNext);posNext = NULL;}

2.9 链表的销毁

//建议传二级指针,因为销毁的话需要把这个指向链表的指针置空
//传一级指针无法把指向链表的指针置空
void SListDestroy(SLTNode** pphead)
{SLTNode* cur = *pphead;while (cur){SLTNode* del = cur;cur = cur->next;free(del);del = NULL;}*pphead = NULL;
}

2.10 链表的打印

void SListPrint(SLTNode* phead)
{SLTNode* cur = phead;while (cur){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");}

三、代码汇总

3.1 SLish.h

#pragma once//SList.h#include <stdio.h>
#include <assert.h>
#include <stdlib.h>typedef int SLTDataType;
typedef struct SLTNode
{SLTDataType data;struct SLTNode* next;}SLTNode;// 动态申请一个节点
extern SLTNode* BuySListNode(SLTDataType x);
// 单链表打印
extern void SListPrint(SLTNode* phead);
// 单链表尾插
extern void SListPushBack(SLTNode** pphead, SLTDataType x);
// 单链表的头插
extern void SListPushFront(SLTNode** pphead, SLTDataType x);
// 单链表的尾删
extern void SListPopBack(SLTNode** pphead);
// 单链表头删
extern void SListPopFront(SLTNode** pphead);
// 单链表查找
extern SLTNode* SListFind(SLTNode* pphead, SLTDataType x);
// 单链表在pos位置之后插入x
// 分析思考为什么不在pos位置之前插入?
extern void SListInsertAfter(SLTNode* pos, SLTDataType x);
// 单链表删除pos位置之后的值
// 分析思考为什么不删除pos位置?
extern void SListEraseAfter(SLTNode* pos);
// 单链表的销毁
extern void SListDestroy(SLTNode** pphead);

3.2 SLish.c

#define _CRT_SECURE_NO_WARNINGS 1
//Slist.c#include "SList.h"SLTNode* BuySListNode(SLTDataType x)
{SLTNode* newNode = (SLTNode*)malloc(sizeof(SLTNode));if (newNode == NULL){perror("malloc fail");return NULL;}else{newNode->data = x;newNode->next = NULL;return newNode;}
}void SListPrint(SLTNode* phead)
{SLTNode* cur = phead;while (cur){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");}void SListPushBack(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newNode = BuySListNode(x);if (*pphead == NULL){*pphead = newNode;}else{SLTNode* tail = *pphead;while (tail->next){tail = tail->next;}tail->next = newNode;}}void SListPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newNode = BuySListNode(x);newNode->next = *pphead;*pphead = newNode;
}void SListPopBack(SLTNode** pphead)
{assert(pphead);assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLTNode* tailPrev = NULL;SLTNode* tail = *pphead;while (tail->next){tailPrev = tail;tail = tail->next;}tailPrev->next = NULL;free(tail);tail = NULL;}}void SListPopFront(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* del = *pphead;*pphead = (*pphead)->next;free(del);del = NULL;}SLTNode* SListFind(SLTNode* pphead, SLTDataType x)
{SLTNode* cur = pphead;while (cur){if (cur->data == x){return cur;}else{cur = cur->next;}}printf("找不到%d\n",x);return NULL;}void SListInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);SLTNode* newNode = BuySListNode(x);SLTNode* posNext = pos->next;pos->next = newNode;newNode->next = posNext;}void SListEraseAfter(SLTNode* pos)
{assert(pos && pos->next);SLTNode* posNext = pos->next;pos->next = posNext->next;free(posNext);posNext = NULL;}void SListDestroy(SLTNode** pphead)
{SLTNode* cur = *pphead;while (cur){SLTNode* del = cur;cur = cur->next;free(del);del = NULL;}*pphead = NULL;
}

3.3 test.c

#define _CRT_SECURE_NO_WARNINGS 1
//test.c#include "SList.h"void test_SListPushBack(void)
{SLTNode* plist = NULL;SListPushBack(&plist, 1);SListPushBack(&plist, 2);SListPushBack(&plist, 3);SListPushBack(&plist, 4);SListPushBack(&plist, 5);SListPrint(plist);SLTNode* ret = SListFind(plist, 1);if (ret != NULL){printf("找到了,地址为:%p\n", ret);SListInsertAfter(ret, 6);SListPrint(plist);}ret = SListFind(plist, 1);if (ret != NULL){printf("找到了,地址为:%p\n", ret);SListInsertAfter(ret, 7);SListPrint(plist);}ret = SListFind(plist, 1);if (ret != NULL){printf("找到了,地址为:%p\n", ret);SListInsertAfter(ret, 8);SListPrint(plist);}ret = SListFind(plist, 1);if (ret != NULL){printf("找到了,地址为:%p\n", ret);SListInsertAfter(ret, 9);SListPrint(plist);}ret = SListFind(plist, 1);if (ret != NULL){printf("找到了,地址为:%p\n", ret);SListInsertAfter(ret, 10);SListPrint(plist);}/*SLTNode* ret = SListFind(plist, 1);if (ret != NULL){printf("找到了,地址为:%p\n", ret);SListEraseAfter(ret);SListPrint(plist);}ret = SListFind(plist, 1);if (ret != NULL){printf("找到了,地址为:%p\n", ret);SListEraseAfter(ret);SListPrint(plist);}ret = SListFind(plist, 1);if (ret != NULL){printf("找到了,地址为:%p\n", ret);SListEraseAfter(ret);SListPrint(plist);}ret = SListFind(plist, 1);if (ret != NULL){printf("找到了,地址为:%p\n", ret);SListEraseAfter(ret);SListPrint(plist);}*//*ret = SListFind(plist, 1);if (ret != NULL){printf("找到了,地址为:%p\n", ret);SListEraseAfter(ret);SListPrint(plist);}*///SListInsertAfter(ret, 8);/*SListPrint(plist);SListPopFront(&plist);SListPrint(plist);SListPopFront(&plist);SListPrint(plist); SListPopFront(&plist);SListPrint(plist); SListPopFront(&plist);SListPrint(plist); SListPopFront(&plist);SListPrint(plist);*/}void test_SListPushFront(void)
{SLTNode* plist = NULL;SListPushFront(&plist, 1);SListPushFront(&plist, 2);SListPushFront(&plist, 3);SListPushFront(&plist, 4);SListPushFront(&plist, 5);SListPrint(plist);SListPopFront(&plist);SListPrint(plist);SListPopFront(&plist);SListPrint(plist);SListPopFront(&plist);SListPrint(plist);SListPopFront(&plist);SListPrint(plist);SListPopFront(&plist);SListPrint(plist);/*SListPopFront(&plist);SListPrint(plist);*///SListDestroy(plist);//SListPrint(plist);/*SListPopBack(&plist);SListPrint(plist);SListPopBack(&plist);SListPrint(plist);SListPopBack(&plist);SListPrint(plist);SListPopBack(&plist);SListPrint(plist);SListPopBack(&plist);SListPrint(plist);*/}int main()
{//test_SListPushBack();test_SListPushFront();return 0;
}

以上就是有关单链表增删查改的全部内容了,你学会了吗?如果对你有帮助,点亮一下小心心,点点关注呗,后期会持续更新计算机相关知识哦!!!

相关文章:

单链表(增删查改)

目录一、什么是单链表&#xff1f;二、单链表的增删查改2.1 结构体变量的声明2.2 申请新结点2.2 链表的头插2.3 链表的尾插2.4 链表的头删2.5 链表的尾删2.6 链表的查找2.7 链表的任意位置后面插入2.8 链表的任意位置后面删除2.9 链表的销毁2.10 链表的打印三、代码汇总3.1 SLi…...

端口复用(bind error: Address already in use 问题)

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 端口复用专栏&#xff1a;《Linux从小白到大神》《网络编程》 在前面讲解TCP状态转换中提到过一个2MSL…...

数字化引领乡村振兴,VR全景助力数字乡村建设

一、数字乡村建设加速经济发展随着数字化建设的推进&#xff0c;数字化农业产业正在成为农业产业发展的主导力量&#xff0c;因此数字化技术赋予农业产业竞争力的能力不可小觑。数字化乡村建设背景下&#xff0c;数字化信息技术将全面改造升级农村产业&#xff0c;从农业、养殖…...

【数据结构入门】-链表之双向循环链表

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【数据结构初阶&#xff08;C实现&#xff09;】 文章目录链表初始化打印链表尾插尾删新建一个节点头插头删查找在pos之前插入*删除pos位…...

Jenkins自动化部署入门

Jenkins自动化部署入门 一、简介 Jenkins是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件的持续集成变成可能。 Jenkins自动化部署实现原理 二、Jenkins部…...

Springboot 读取模板excel信息内容并发送邮件, 并不是你想想中的那么简单

Springboot 读取模板excel信息内容并发送邮件 背景技术选型搭建过程数据加密隐藏问题暴露背景追溯解决背景 在我们日常开发中, 会遇到这样一种场景, 就是读取表格中的数据, 并将数据以附件的形式通过邮箱发送到表格中的每个人 即: excel 读取 excel 写入 发送邮件(携带附件), 例…...

蓝桥杯真题31日冲刺 |第一天

蓝桥杯真题31日冲刺 |第一天 一&#xff1a;完全平方数 题目&#xff1a;[链接](完全平方数 - 蓝桥云课 (lanqiao.cn)) 思路&#xff1a; 将 每个 完全平方数都 消掉&#xff0c;剩下的就是 不能构成平方的数 以12 为例&#xff1a; 所以 12 只要再 乘个三 即可满足 代…...

STM32开发(18)----CubeMX配置RTC

CubeMX配置RTC前言一、什么是RTC&#xff1f;RTC时钟源RTC备份域二、实验过程1.CubeMX配置2.代码实现3.实验结果总结前言 本章介绍使用STM32CubeMX对RTC进行配置的方法&#xff0c;RTC的原理、概念和特点&#xff0c;配置各个步骤的功能&#xff0c;并通过实验方式验证。 一、…...

Qt 单例模式第一次尝试

文章目录摘要单例模式如何使用Qt 的属性系统总结关键字&#xff1a; Qt、 单例、 的、 Q_GLOBAL_STATIC、 女神节摘要 世界上第一位电脑程序设计师是名女性&#xff1a;Ada Lovelace (1815-1852)是一位英国数学家兼作家&#xff0c;她是第一位主张计算机不只可以用来算数的人…...

C语言--一维数组

数组概念 数组&#xff1a;是一种构造数据类型&#xff0c;用以处理批量的同种类型的数据。 主要特点&#xff1a;数据量大 &#xff0c;类型相同 一维数组的定义 语法&#xff1a; 类型说明符 数组名[整型常量表达式]&#xff1b; 注意&#xff1a; 方括号里面的内容用于指…...

DataGear 4.5.1 发布,数据可视化分析平台

DataGear 4.5.1 发布&#xff0c;严重 BUG 修复&#xff0c;具体更新内容如下&#xff1a; 修复&#xff1a;修复SQL数据集对于DB2、SQLite等数据源预览时会报错的BUG&#xff1b;修复&#xff1a;修复系统对于MySQL、MariaDB等数据源中无符号数值类型有时报错的BUG&#xff1…...

Springboot——@valid 做字段校验和自定义注解

文章目录前言注意实现测试环境验证自带的注解自定义valid注解自定义注解和处理类创建参数接收类&#xff0c;并增加字段注解接口中使用自测环节正常测试异常测试自定义全局异常监听扩展递归参数下valid不识别的坑前言 再项目开发中&#xff0c;针对前端传递的参数信息&#xf…...

c语言基础练习题详解

&#x1f49e;&#x1f49e; 1.C语言程序的基本单位是&#xff08;C&#xff09;。 A&#xff0e;程序行 B&#xff0e; 语句 C&#xff0e; 函数 D&#xff0e;字符 &#x1f49e;&#x1f49e; 2.已知各变量的类型说明如下&#xff1a; int m6,n,a,b; unsigned long w8;…...

C语言设计模式:实现简单工厂模式和工程创建

目录 一&#xff0c;设计模式概念引入 ① 什么是设计模式 ② 什么是类和对象 ③ 什么是工厂模式 二&#xff0c;C语言工厂模式的实现 ① 普通类和对象的代码实现 ② 工厂模式代码实现 ● cat.c ● dog.c ● person.c ● animal.h ● mainpro.c ● 完善mainpro.c …...

3.6日报

今天进行3.0信号整理工作 做官网后台技术文档 了解grpc gRPC是rpc框架中的一种&#xff0c;是rpc中的大哥 是一个高性能&#xff0c;开源和通用的RPC框架&#xff0c;基于Protobuf序列化协议开发&#xff0c;且支持众多开发语言。 面向服务端和协议端&#xff0c;基于http…...

中文代码88

PK 嘚釦 docProps/PK 嘚釦|,g z docProps/app.xml漅AN??駠(髂v诖m岼侸 魣,g踃$秂D廋Qvf漶x莗笳w?:瘜^?俍欶辇2}?睧汎 t#:?效7治XtA鏊?羄鈋嫿饄攗Tv契"D桷撵vJ鉂?闌 Jg??浱?樱沲gic鋹峡?sū窛葻?]迾?9卑{艏 rk\?洺萹啰N?W??2&quo…...

ElasticSearch 基础(五)之 映射

目录前言一、映射&#xff08;Mapping&#xff09;简介二、动态映射&#xff08;Dynamic mapping&#xff09;1、动态字段映射1.1、日期检测1.1.1、禁用日期检测1.1.2、自定义检测到的日期格式1.2、数值检测2、动态模板三、显示映射&#xff08;Explicit mapping&#xff09;1、…...

【C语言督学训练营 第二天】C语言中的数据类型及标准输入输出

文章目录一、前言二、数据类型1.基本数据类型①.整形②.浮点型③.字符型2.高级数据类型3.数据分类①.常量②.变量三、标准输入输出1.scanf2.printf四、进制转换1.进制转换简介2.十进制转其他进制3.其他进制转换五、OJ网站的使用一、前言 王道2024考研408C语言督学营第二天&…...

重资产模式和物流网络将推动京东第四季度利润率增长

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 强劲的2022年第三季度财务业绩 2022年11月18日&#xff0c;京东&#xff08;JD&#xff09;公布了2022年第三季度财务业绩&#xff0c;净收入为2435亿元人民币&#xff0c;增长了11.4%。净服务收入为465亿元人民币&#xf…...

【新】EOS至MES的假捻报工数据导入-V2.0版本

假捻自动线的数据和MES没有进行对接,直接入库至EOS。 因此可信平台上缺少这部分的报工数据,需要把EOS的入库数据导出,整理成报工数据,导入到MES,然后通过定时任务集成到可信平台。 MES这边的报工数据整理,主要是添加订单明细ID,和完工单号。 订单明细ID(根据批次号和…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...