单链表<数据结构 C版>

目录

概念

 链表的单个结点

 链表的打印操作

新结点的申请

尾部插入

头部插入

尾部删除

头部删除

查找

在指定位置之前插入数据

在任意位置之后插入数据

测试运行一下:

 删除pos结点

 删除pos之后结点

 销毁链表


概念

单链表是一种在物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接顺序实现的。

链表的每个结点有两个部分,分别是数据和指向下个结点的指针,每个链表的最后一个结点的下一个结点为NULL(不能对NULL解引用)。

放一张bit课件里的图,我觉得很形象:


 链表的单个结点

typedef int SLDataType;//重定义一下在链表内存放的数据类型,方便后期对类型进行统一修改//链表的单个结点
typedef struct SListNode {//Single List Node :链表结点SLDataType data;//存放的数据struct SListNode* next;//指向下一个结点的指针
}SLNode;//重定义名字方便后期使用

 链表的打印操作

//链表的打印操作
void SLPrint(SLNode* phead) {assert(phead);//不能传入空指针SLNode* pcur = phead;//pointer cursor:指针光标,不让头结点丢失(虽然不会改变头结点的指向)while (pcur) {//等同于pcur!=NULLprintf("%d->", pcur->data);//打印此结点的数据pcur = pcur->next;//使pcur指向下一个结点}printf("NULL\n");
}

新结点的申请

后面会涉及到新结点的插入,申请新结点可以封装成一个函数,避免代码冗余

//新结点的申请
SLNode* SLBuyNode(SLDataType x) {SLNode* node = (SLNode*)malloc(sizeof(SLNode));if (!node) {//返回值为空,申请失败(一般是空间不足了),直接退出perror("malloc fail");exit(1);}node->data = x;//将数据赋给datanode->next = NULL;//将下一个节点置为NULL;return node;
}

尾部插入

//尾部插入
void SLPushBack(SLNode** pphead, SLDataType x) {//注意在这里我们传参的是二级指针,因为我们需要在函数内部改变头结点的指向assert(pphead);//不能传NULL//新结点的申请SLNode* node=SLBuyNode(x);if (*pphead == NULL) {*pphead = node;}else {SLNode* pcur = *pphead;while (pcur->next) {//找到next元素为NULL的结点,也就是为链表尾部pcur = pcur->next;}pcur->next = node;}}

测试运行一下:


头部插入

//头部插入
void SLPushFront(SLNode** pphead, SLDataType x) {assert(pphead);SLNode* node = SLBuyNode(x);//这里需要处理头结点为空的情况吗?不需要,因为没有涉及到解引用其元素node->next = *pphead;*pphead = node;
}

测试运行一下:


尾部删除

//尾部删除
void SLPopBack(SLNode** pphead) {assert(*pphead && pphead);//if (!(*pphead)->next) {//处理只有一个元素的情况free(*pphead);*pphead = NULL;}else {SLNode* prev = NULL;SLNode* pcur = *pphead;while (pcur->next) {//找到尾结点前一个结点prev = pcur;pcur = pcur->next;}free(pcur);//将尾结点释放pcur = NULL;prev->next = NULL;//将尾结点的前一个结点的next元素置为NULL}
}

测试运行一下:


头部删除

//头部删除
void SLPopFront(SLNode** pphead) {assert(*pphead && pphead);SLNode* next = (*pphead)->next;//保存头结点的下一个结点地址free(*pphead);//释放头结点*pphead = next;//使头结点指向下一个结点
}

测试运行一下:


查找

在链表中想要对指定位置进行操作不能使用下标,所以我们必须找到指定位置的地址才能对其进行操作。

//查找
SLNode* SLFind(SLNode* phead, SLDataType x) {assert(phead);SLNode* pcur = phead;while (pcur) {if (pcur->data == x) {return pcur;}pcur = pcur->next;}return NULL;
}

在指定位置之前插入数据

//在指定位置之前插入数据
void SLInsert(SLNode** pphead, SLNode* pos, SLDataType x) {assert(pphead && pos && *pphead);//pos和pphead不能为空,以及pphead指向空间不能为空if (*pphead == pos) {//处理头插的情况SLPushFront(pphead,x);}else {SLNode* node = SLBuyNode(x);SLNode* pcur = *pphead;while (pcur->next != pos) {//找到pos前一个结点pcur = pcur->next;}node->next = pcur->next;pcur->next = node;}
}

测试运行一下:


在任意位置之后插入数据

//在任意位置之后插入数据
void SLInsertAfter(SLNode* pos, SLDataType x) {assert(pos);//pos不能为空SLNode* node = SLBuyNode(x);node->next = pos->next;pos->next = node;
}

测试运行一下:


 删除pos结点

//删除pos结点
void SLErase(SLNode** pphead, SLNode* pos) {assert(*pphead && pphead && pos);if (*pphead == pos) {//处理头删的情况SLPopFront(pphead);}else {SLNode* pcur = *pphead;while (pcur->next!= pos) {pcur = pcur->next;}pcur->next = pos->next;free(pos);pos = NULL;}
}

 测试运行一下:


 删除pos之后结点

//删除pos之后结点
void SLEraseAfter(SLNode* pos) {assert(pos && pos->next);//pos后面的结点也不能为空SLNode* next = pos->next;pos->next = next->next;free(next);next = NULL;
}

 测试运行一下:

 


 销毁链表

//销毁链表
void SLDestory(SLNode** pphead) {assert(pphead && *pphead);SLNode* pcur = *pphead;while (pcur) {SLNode* nextnode = pcur->next;//使用一个变量接受下一个结点地址free(pcur);pcur = nextnode;}*pphead = NULL;
}

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

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

相关文章

【C语言】 利用栈完成十进制转二进制(分文件编译,堆区申请空间malloc)

利用栈先进后出的特性,在函数内部,进行除二取余的操作,把每次的余数存入栈内,最后输出刚好就是逆序输出,为二进制数 学习过程中,对存储栈进行堆区的内存申请时候,并不是很熟练,一开始…

Linux操作系统的有关常用的命令

1.linux系统的概述 1.1 什么是Linux系统? Linux,全称GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,其内核由林纳斯本纳第克特托瓦 兹(Linus Benedict Torvalds)于1991年10月5日首次发布,它主要受…

Unity 调试死循环程序

如果游戏出现死循环如何调试呢。 测试脚本 我们来做一个测试。 首先写一个死循环代码: using System.Collections; using System.Collections.Generic; using UnityEngine;public class dead : MonoBehaviour {void Start(){while (true){int a 1;}}}Unity对象设…

matlab simulink气隙局部放电仿真技术研究

1、内容简介 略 87-可以交流、咨询、答疑 2、内容说明 略 为了解决目前国内外局部放电仿真方法难以计算气隙局部放电暂态过程的问题 , 利用 MATLAB (SIMULINK ) 的公共模块库和电力系统专业模块库 , 根据单气隙局部放电仿真物理模型 , 构造了气隙局部放 电仿真计算的电…

C++_单例模式

目录 1、饿汉方式实现单例 2、懒汉方式实现单例 3、单例模式的总结 结语 前言: 在C中有许多设计模式,单例模式就是其中的一种,该模式主要针对类而设计,确保在一个进程下该类只能实例化出一个对象,因此名为单例。而…

新能源风机视觉数据集

需要的同学私信联系,推荐关注上面图片右下角平台自取下载。 全球风电装机的快速扩张推高了风电场运维巡检的需求,原本高度依赖人力的风电运维巡检工作正因智能化、数字化、无人化技术的应用出现变革。AI智慧风机检测可以促进风电领域运维检测新技术产、…

操作系统——文件管理

1)什么是文件? 2)单个文件的逻辑结构和物理结果之间是否存在制约关系? 本节内容较为抽象,本节要注意区分文件的逻辑结构和物理结构。 一、文件系统基础 1.文件的基本概念(一切皆文件) 文件&…

【漏洞复现】Netgear WN604 downloadFile.php 信息泄露漏洞(CVE-2024-6646)

0x01 产品简介 NETGEAR WN604是一款由NETGEAR(网件)公司生产的无线接入器(或无线路由器)提供Wi-Fi保护协议(WPA2-PSK, WPA-PSK),以及有线等效加密(WEP)64位、128位和152…

AVL树超详解上

前言 学习过了二叉树以及二叉搜索树后(不了解二叉搜索树的朋友可以先看看这篇博客,二叉搜索树详解-CSDN博客),我们在一般情况下对于二叉搜索树的插入与查询时间复杂度都是O(lgN),是十分快的,但是在一些特殊…

视频监控平台LntonCVS视频融合共享平台智慧安防视频监控汇聚应用方案

LntonCVS是一款功能强大且灵活部署的安防视频监控平台。它支持多种主流标准协议,包括GB28181、RTSP/Onvif、RTMP等,同时能够兼容海康Ehome、海大宇等厂家的私有协议和SDK接入。该平台不仅提供传统的安防监控功能,还支持接入AI智能分析&#x…

医疗器械产品的 EMC(电磁兼容性)中A、B、C、D 类的区别是什么

在医疗器械产品的 EMC(电磁兼容性)中,按照 GB 17625.1 标准的分类,A、B、C、D 类的区别主要在于设备的谐波电流发射限值不同。 A 类设备:平衡的三相设备、不归属 B、C 或 D 类的设备、家用电器(不包括列入 …

TiDB实践—索引加速+分布式执行框架创建索引提升70+倍

作者: 数据源的TiDB学习之路 原文来源: https://tidb.net/blog/92d348c2 背景介绍 TiDB 采用在线异步变更的方式执行 DDL 语句,从而实现 DDL 语句的执行不会阻塞其他会话中的 DML 语句。按照是否需要操作 DDL 目标对象所包括的数据来划分…

直播带货还是新电商吗?

现在已经没有新电商和老电商区分,抖音现直播电商现在也算是传统电商了。直播电商这几年听起来非常的火热,但是它有天花板,最多也就3万亿的市场规模,为什么呢?因为它是基于 IP 模型的,有非常强的头部效应。 …

一分钟图情论文:《叙事信息的语义表示与组织结构研究》

叙事作为人类知识与信息交流的重要方式,其语义建模、形式化表示与组织在数智时代显得尤为重要。近日,由曲阜师范大学和武汉大学的侯西龙、王晓光教授合著论文《叙事信息的语义表示与组织结构研究》从语义表示和组织结构视角出发审视了叙事信息的复杂性和…

电子画册制作利器大揭秘,提升销量全靠它

​随着科技的不断发展,电子画册逐渐成为企业营销的新宠。它以生动活泼、互动性强的特点,吸引了众多消费者的目光。而一款优秀的电子画册制作利器,更是为企业提升了销量,实现了营销目标。本文将为大家揭秘电子画册制作的利器&#…

《基于 Kafka + Quartz 实现时限质控方案》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…

密码学基础-Hash、MAC、HMAC 的区别与联系

密码学基础-Hash、MAC、HMAC 的区别与联系 Hash Hash 是一种从一段数据中创建小的数字“指纹”的方法。就像一个人的指纹代表一个人的信息一样,Hash 对输入的数据进行整理,生成一个代表该输入数据的“指纹” 数据。通常该指纹数据也可称之为摘要、散列…

linux配置podman阿里云容器镜像加速器

1.下载podman yum install -y podman systemctl status podman systemctl start podman 2.获取阿里云个人容器镜像加速器地址 访问阿里云官网:首先,您需要访问阿里云(Alibaba Cloud)的官方网站。阿里云官网的URL是:…

TinyVue:与 Vue 交往八年的组件库

本文由体验技术团队莫春辉老师原创~ 去年因故停办的 VueConf,今年如约在深圳举行。作为东道主 & 上届 VueConf 讲师的我,没有理由不来凑个热闹。大会结束后,我见裕波在朋友圈转发 Jinjiang 的文章《我和 Vue.js 的十年》,我就…

如何发一篇顶会论文? 涉及3D高斯,slam,自动驾驶,三维点云等等

SLAM&3DGS 1)SLAM/3DGS/三维点云/医疗图像/扩散模型/结构光/Transformer/CNN/Mamba/位姿估计 顶会论文指导 2)基于环境信息的定位,重建与场景理解 3)轻量级高保真Gaussian Splatting 4)基于大模型与GS的 6D pose e…