链表之单链表

上一篇博客我们学习了线性表中的顺序表,这一篇博客让我们继续往下了解线性表的链表,链表分为好几种结构,活不多说,让我们开始学习吧!


目录

1.链表

2.链表的结构

3.单链表的实现


1.链表

1.概念:它是一种物理存储结构上非连续非顺序的存储结构,数据元素的逻辑顺序是通过链                表中的指针链接次序实现的。它在空间上,按需给空间,不要求物理空间的连续,                和顺序表不同,它头部和中间的数据的插入就不需要挪动数据。链表的实现是通过                指针的。

2.有些老铁可能不明白什么是物理结构,它就是在内存中实实在在的存储形式。

什么是不连续非顺序,我们画图来给大家解释一下:

在这些节点中间,我们可以插入新的节点,又是新的地址,所以说它不是按顺序走的。这些节点在内存中,可能这有一个节点,也可能那有一个节点,但它们彼此之间通过指针相连接,只要指针不断,就可以找到下一个节点。

3.链表只能一个一个诶个访问,只能从头找,因为一旦它找到下一个节点,它就不知道上一个节点的位置了(双向链表可以找到上一个,我们到了那个章节在继续学习)。这时,又显示出顺序表的好处了,因为它可以直接定位到要查找数据的位置,但是它会造成空间的浪费,所以说有好有坏,需要大家自己体会。

2.链表的结构

链表分为八种结构,在这里先给大家一个总体的框架,方便接下来的学习:

单链表,双链表,不带头链表,带头链表,循环链表,不循环链表,这六种链表构成了链表的八种结构,分别是:

1.单向不带头不循环链表

2.单向不带头循环链表

3.单向带头不循环链表

4.单向带头循环链表

5.双向不带头不循环链表

6.双向不带头循环链表

7.双向带头不循环链表

8.双向带头循环链表

我们今天在这里会实现第一种结构,单向不带头不循环链表,相信通过这个链表的实现,大家可以把2,3,4种结构都实现。

3.单链表的实现

现在我们来实现这个单链表,可以类比顺序表写,这一部分的代码都大差不差,具体要看怎么实现。

SList.h文件

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int ALTDataType;//创建结构体,用来创建链表组成元素
typedef struct SListNode
{ALTDataType data;//链表数据struct SListNode* next;//链表指向下一个元素的指针,指向下一个节点的位置
}SLN;//开辟空间来存入数据
SLN* BuySListNode(ALTDataType x);
//打印链表
void SListPrint(SLN* phead);
//头插
void sListPushFront(SLN** pphead, ALTDataType x);
//尾插
void sListPushBack(SLN** pphead, ALTDataType x);
//头删
void sListPopFront(SLN** pphead);
//尾删
void sListPopBack(SLN** pphead);
//查找链表
SLN* sListFind(SLN* phead, ALTDataType x);
//修改对应链表位置的数据
void sListModify(SLN* phead, SLN* pos, ALTDataType x, ALTDataType y);
//任意位置的插入,在pos位置的前一个位置插入
void sListInsert(SLN** pphead, SLN* pos, ALTDataType x);
//任意位置的删除
void sListErase(SLN** pphead, SLN* pos);
//销毁链表
void destorySList(SLN* phead);

SList.c文件

#include"SList.h"//开辟空间来存入数据
SLN* BuySListNode(ALTDataType x)
{SLN* newnode = (SLN*)malloc(sizeof(SLN));if (newnode == NULL){perror("malloc");return NULL;}newnode->data = x;newnode->next = NULL;return newnode;
}//打印链表
void SListPrint(SLN* phead)
{assert(phead);SLN* cur = phead;while (cur){printf("%d->", cur->data);cur = cur->next;}printf("\n");
}//头插
//想要头插,我们要把新节点的地址给到头节点,再把新节点定义为新的头节点
void sListPushFront(SLN** pphead, ALTDataType x)
{SLN* newnode = BuySListNode(x);newnode->next = *pphead;*pphead = newnode;
}//尾插
void sListPushBack(SLN** pphead, ALTDataType x)
{SLN* newnode = BuySListNode(x);//若一开始链表为空,我们直接插入一个新节点if (*pphead == NULL){*pphead = newnode;}//我们要创建一个变量,找到链表的尾端,从尾端插入SLN* tail = *pphead;while (tail->next){tail = tail->next;}tail->next = newnode;//尾节点链接新节点
}//头删
void sListPopFront(SLN** pphead)
{assert(*pphead);SLN* next = (*pphead)->next;//*小于->的优先级,编译器不通过free(*pphead);*pphead = NULL;*pphead = next;
}
//尾删
void sListPopBack(SLN** pphead)
{assert(*pphead);//当只有一个节点时if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;return;}SLN* tail = *pphead;SLN* prev = NULL;while (tail->next){prev = tail;tail = tail->next;}free(tail);tail = NULL;prev->next = NULL;
}
//查找链表
SLN* sListFind(SLN* phead, ALTDataType x)
{assert(phead);SLN* cur = phead;while (cur){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}
//修改对应链表位置的数据
void sListModify(SLN* phead, SLN* pos, ALTDataType x, ALTDataType y)
{pos = sListFind(phead, x);pos->data = y;
}
//任意位置的插入,在pos位置的前一个位置插入
void sListInsert(SLN** pphead, SLN* pos, ALTDataType x)
{if (pos == *pphead){sListPushFront(pphead, x);return;}SLN* newnode = BuySListNode(x);SLN* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = newnode;newnode->next = pos;
}
//任意位置的删除,删除pos位置的值
void sListErase(SLN** pphead, SLN* pos)
{if (pos == *pphead){sListPopFront(pphead);return;}SLN* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;
}
//销毁链表,这些空间,我们要一个一个释放,防止内存泄漏
void destorySList(SLN* phead)
{assert(phead);SLN* tail = phead->next;while (tail){SLN* next = tail->next;free(tail);tail = NULL;tail = next;}free(phead);phead = NULL;
}

test.c文件

#include"SList.h"void Test1()
{SLN* plist = NULL;SLN* pos = NULL;sListPushFront(&plist, 4);sListPushFront(&plist, 3);sListPushFront(&plist, 2);sListPushFront(&plist, 1);SListPrint(plist);sListPushBack(&plist, 5);sListPushBack(&plist, 6);sListPushBack(&plist, 7);sListPushBack(&plist, 8);SListPrint(plist);sListPopFront(&plist);sListPopFront(&plist);SListPrint(plist);sListPopBack(&plist);sListPopBack(&plist);SListPrint(plist);pos = sListFind(plist, 5);if (pos == NULL){printf("找不到该数据\n");}else{printf("已找到该数据,现在进行修改\n");sListModify(plist, pos, 5, 50);}SListPrint(plist);pos = sListFind(plist, 50);if (pos == NULL){printf("找不到该数据\n");}else{printf("已找到该数据,现在进行在pos前插入数据\n");sListInsert(&plist, pos, 20);}SListPrint(plist);pos = sListFind(plist, 20);if (pos == NULL){printf("找不到该数据\n");}else{printf("已找到该数据,现在进行对pos位置数据的删除\n");sListErase(&plist, pos);}SListPrint(plist);destorySList(plist);printf("链表已销毁\n");
}
int main()
{Test1();return 0;
}

结果:大家下去还是要自己敲一遍代码,才能做到掌握


好了,今天的内容就是这些,我们下期再见铁汁们!

感谢品读!!!

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

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

相关文章

Windows安装SSH超详细教程

在数字化飞速发展的今天,远程连接已经成为我们日常工作和生活中不可或缺的一部分。SSH(Secure Shell)作为一种安全可靠的远程连接方式,受到了广大用户的青睐。那么,如何在Windows系统上安装SSH呢?本文将为你提供一份详尽的教程,让你轻松开启远程连接新纪元。 一、SSH安…

爬虫开发教程及案例

爬虫开发是一种自动化获取网页信息的技术&#xff0c;广泛应用于数据采集、信息监控等领域。以下是一些爬虫开发的教程和案例资源&#xff0c;可以帮助你入门和提升爬虫开发技能。 ### 爬虫开发教程 #### 1. 基础入门 - **了解爬虫**&#xff1a;爬虫是一种自动抓取互联网信息…

大创项目推荐 深度学习 python opencv 火焰检测识别 火灾检测

文章目录 0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 数据集准备5.1 数…

Windows下Docker创建Mysql5.7

安装 下载镜像&#xff0c;注意&#xff0c;要带版本号 docker pull mysql:5.7 等下载完成执行命令&#xff1a; 错误命令1&#xff0c;直接Windows下路径&#xff1a; docker run --name mysql57 --restartalways -p 3306:3306 -v F:/mysqldata/data57/log:/var/log/mysql…

HTML - 请你谈一谈 iframe的优缺点

难度级别:中级及以上 提问概率:50% iframe是一个HTML标签,它可以在一个网页中嵌入另外一个网页,甚至是把其他的网站嵌入进来。在之前的很长时间里,内部管理系统都在使用iframe,做为菜单切换的主体模板区域框架。iframe包含一个src属性,…

php运行python脚本失败怎么解决

假设有文件&#xff1a;php_test.php python_test.py 在php文件中运行Python&#xff1a; exec("python python_test.py", $array, $ret); 如果运行Python出错并不能保存在数组array中&#xff0c;因此应该把标准错误重定向到文件中&#xff0c;以上代码改写如下&a…

【芯片验证】通关寄存器与ral_model —— 寄存器生成流程中加入backdoor后门配置

前言 【芯片验证】通关寄存器与ral_model —— backdoor后门访问实操测试-CSDN博客 上一篇文章中,我们通过在环境中配置后门路径的方式来实现了寄存器的后门访问,但是在实际应用中,无论寄存器RTL文件、例化还是寄存器模型大概率都是工具生成的,比如在本专栏中实现的gen_r…

Docker实战教程 第2章 Docker基础

3-1 Docker介绍 什么是Docker 虚拟化&#xff0c;容器 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从Apache2.0协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&…

自动驾驶中各种坐标系辨析

坐标系辨析 0. 地球椭圆体1. 大地坐标系2. eci地心惯性坐标系3. 地心地固坐标系(ECEF坐标系&#xff0c;E系)4. 站心坐标系(ENU坐标系)5. UTM坐标系6. LTM坐标系7. IMU坐标系8. 代码部分8.1 LLA(大地坐标系坐标、经纬度海拔)坐标转LTM系(ENU系)下的三维笛卡尔坐标8.2 LLA坐标转…

AI大模型学习浅谈

目录 一&#xff1a;AI大模型学习的理论基础 1.数学基础 2.算法原理 3.模型架构设计 4.大规模数据处理的优势与挑战 二&#xff1a;AI大模型的训练与优化 1. 计算资源分配 2. 参数调优 3. 正则化方法 4. 模型压缩 5. 分布式和并行计算 6. 自动调参 三&#xff1a;…

代码随想录算法训练营第四十二天| 01背包问题 01背包问题 滚动数组 416. 分割等和子集

正式开始背包问题&#xff0c;背包问题还是挺难的&#xff0c;虽然大家可能看了很多背包问题模板代码&#xff0c;感觉挺简单&#xff0c;但基本理解的都不够深入。 如果是直接从来没听过背包问题&#xff0c;可以先看文字讲解慢慢了解 这是干什么的。 如果做过背包类问题&am…

运动伤害预防的实际案例

运动伤害预防是一个复杂的过程&#xff0c;涉及到运动员的体态分析、动作监测和潜在风险评估。在实际应用中&#xff0c;通常会结合传感器数据和图像识别技术来实现。以下是一个简化的案例&#xff0c;展示如何使用Python和OpenCV库来监测运动员的动作&#xff0c;并给出潜在伤…

线上线下陪玩,APP小程序H5。源码交付,支持二开!

线下陪玩的风险与管理方式 1、陪玩者的身心健康风险 线下陪玩的模式决定了陪玩者需要与不同的需求方见面&#xff0c;并满足他们的陪伴和娱乐需求。这种工作方式可能会给陪玩者带来身心上的压力和负担。因为陪玩者需要面对各种需求方的要求&#xff0c;有时还需要虚拟出一种完…

HTML - 你知道b与strong标签的区别吗

难度级别&#xff1a;初级及以上 提问概率&#xff1a;50% 不单单是初学者&#xff0c;即便是有好几年工作经验的前端开发工作者&#xff0c;也会有一大部分人把这两个标签搞混&#xff0c;甚至在工作中&#xff0c;很大一部人不会使用这两个标…

212 基于matlab的双稳态随机共振的算法

基于matlab的双稳态随机共振的算法&#xff0c;分析信噪比随系统参数a,b及乘性噪声和加性噪声的增益变化曲线&#xff0c;60个数据样本可供选择。程序已调通&#xff0c;可直接运行。 212 双稳态随机共振 信噪比增益变化曲线 - 小红书 (xiaohongshu.com)

一些常见的jenkins问题和答案

什么是 Jenkins&#xff1f;它的主要功能是什么&#xff1f; Jenkins 是一个开源的持续集成和持续交付工具。它的主要功能是自动化构建、测试和部署软件项目。 Jenkins 是如何实现持续集成的&#xff1f; Jenkins通过不断监测版本控制系统中的代码变化&#xff0c;触发构建过程…

设计模式(16):观察者模式

核心 观察者模式主要用于1&#xff1a;N的通知。当一个对象(目标对象Subject或者Abservable)的状态变化时&#xff0c;他需要及时告知一系列对象(观察者对象&#xff0c;Observer),令 他们做出响应。通知观察者的方式&#xff1a; 推: 每次都会把通知以广播方式发送给所有观察…

浅谈分布式光伏电站的运维管理

摘要&#xff1a;随着近些年我国对节能降耗关注力度的持续加大&#xff0c;为满足人们不断增长的电能需求&#xff0c;光伏发电产业得到迅猛发展&#xff0c;其中分布式光伏发电的比重持续增长。在打赢脱贫攻坚战的大背景下&#xff0c;国家电网公司探索出一条“阳光扶贫”的扶…

康耐视visionpro-CogPMAlignTool工具详细说明

图案位置搜索工具 可在图像中找到你训练的特征所在的位置等信息 基于边缘特征的模板而不是基于像素的模板匹配&#xff0c;比像素格栅表现更快捷准确支持旋转和缩放 三种主要算法&#xff1a;PatMax&#xff08;精度最高&#xff09;, PatQuick&#xff08;速度最快&#xff0…

Spring Cloud微服务入门(一)

微服务的演变过程 //controller 视图交互层 前端数据处理传给service //1.DAO RequestBody userDAO String id;String type; {"id":"lcs", "type":"lcs"} //2.GET请求 findUserById&#xff1f;id1&typelcsRequestParam String …