数码产品网站建设策划书/苏州seo网站公司
目录
什么是单向链表
顺序表和链表的区别和联系
顺序表:
链表:
链表表示(单项)和实现
1.1 链表的概念及结构
1.2单链表(无头)的实现
所用文件
将有以下功能:
链表定义
创建新链表元素
尾插
头插
尾删
头删
查找-给一个节点的指针
改
pos位置之前插入
删除pos位置的值
成品展示
SList.h
SList.c
test.c
什么是单向链表
单向链表是一种常见的线性数据结构,它由一系列节点组成,每个节点包含两部分:数据和指向下一个节点的指针。每个节点只能访问它后面的节点,而不能访问前面的节点。
单向链表的特点:
- 每个节点包含数据和指向下一个节点的指针。
- 最后一个节点的指针指向空值(NULL),表示链表的结束。
- 可以动态地添加或删除节点,链表的长度可以根据需要进行扩展或缩小。
- 可以根据指针迅速插入或删除节点,而不需要移动其他节点。
单向链表相对于数组来说,具有一些优点和缺点:
- 优点:插入和删除元素的时间复杂度为O(1),不需要像数组一样进行元素的移动;链表长度可以动态调整,没有固定大小的限制。
- 缺点:要访问特定位置的元素需要从头开始遍历,时间复杂度为O(n);相比于数组,在使用额外的指针存储下一个节点的信息,会占用更多的内存空间。
由于单向链表的特点,它常常被用于需要频繁插入和删除元素的场景,或者在事先无法确定数据大小和数量的情况下使用。
顺序表和链表的区别和联系
顺序表:
优点:
空间连续、支持随机访问
缺点:
- 中间或前面部分的插入删除时间复杂度O(N)
- 2.增容的代价比较大。
链表:
缺点:
以节点为单位存储,不支持随机访问
优点:
- 任意位置插入删除时间复杂度为O(1)
- 没有增容消耗,按需申请节点空间,不用了直接释放。
链表表示(单项)和实现
1.1 链表的概念及结构
概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表
中的指针链接次序实现的
1.2单链表(无头)的实现
- 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结
构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。- 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都
是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带
来很多优势,实现反而简单了,后面我们代码实现了就知道了。
所用文件
定义三个文件:
- 头文件 SList.h
- 函数的实现SList.c
- 代码的测试test.c
将有以下功能:
//打印链表
void SListPrint(SLTNode* phead);//创建新链表元素(动态申请一个节点)
SLTNode* BuySListNode(SLTDataType x);//尾插
void SListPushBack(SLTNode** pphead, SLTDataType x);//头插
void SListPushFront(SLTNode** pphead, SLTDataType x);//尾删
void SListPopBack(SLTNode** pphead);//头删
void SListPopFront(SLTNode** pphead);//查找->可在查找的基础上进行修改SListAlter
SLTNode* SListFind(SLTNode* phead,SLTDataType x);//改
void SListAlter(SLTNode* phead, SLTDataType x,SLTDataType y);//pos位置之前插入
void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);//删除pos位置的值
void SListErase(SLTNode** pphead, SLTNode* pos);
链表定义
定义链表基本结构
typedef struct SListNode
{int data;struct SListNode* next;
}SLTNode;
创建新链表元素
创建新元素用于插入原链表
SLTNode* BuySListNode(SLTDataType x)
{//开辟空间SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));assert(newnode);newnode->data = x;newnode->next = NULL;return newnode;
}
尾插
void SListPushBack(SLTNode** pphead, SLTDataType x)
{//开辟空间SLTNode* newnode = BuySListNode(x);if (*pphead == NULL){//防止开始时节点为空*pphead = newnode;}else{//找尾节点SLTNode* tail = *pphead;//找到链表首元素while (tail->next != NULL){//检索到未节点tail = tail->next;}//插入tail->next = newnode;}
}
头插
void SListPushFront(SLTNode** pphead, SLTDataType x)
{SLTNode* newnode = BuySListNode(x);newnode->next = *pphead;*pphead = newnode;//地址传给pphead //*pphead=&plist/*头插无需检查是否为空*/
}
尾删
void SListPopBack(SLTNode** pphead)
{assert(*pphead);if ((*pphead)->next==NULL){//1,只有一个节点free(*pphead);*pphead = NULL;}else{//2,有多个节点//将前一个链元素中存放的地址换为NULL,防止野指针/* 写法一 */SLTNode* tailPrev = NULL;SLTNode* tail = *pphead;while (tail->next!=NULL){tailPrev = tail;//tail的地址tail = tail->next;}free(tail);tailPrev->next = NULL;/* //写法二* //tail寻找的是倒数第二个元素while (tail->next->next!=NULL){tail = tail->next;}free(tail->next);tail->next = NULL;*/}
}
头删
void SListPopFront(SLTNode** pphead)
{ //防止被删空assert(*pphead);//找到首位链表元素SLTNode* next = (*pphead)->next;//存储首元素存放下一个元素的地址free(*pphead);//释放首元素*pphead = next;//将第二位元素改为首元素
}
查找-给一个节点的指针
//无需更改元素,故传一级指针
SLTNode* SListFind(SLTNode* phead, SLTDataType x)
{SLTNode* cur = phead;while (cur){if (cur->data==x)return cur;cur = cur->next;}//未找到指定元素,返回NULLreturn NULL;
}
改
改元素是建立再查找基础之上进行更改
void SListAlter(SLTNode* phead, SLTDataType x, SLTDataType y)
{printf("修改成功:\n");//先找到相应元素,再进行更改SLTNode* ret = SListFind(phead, y);ret->data = x;
}
pos位置之前插入
任意位置之前插入
void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pphead);assert(pos);//头插if (pos == *pphead)SListPushFront(pphead, x);else{ //任意位置之前插入SLTNode* prev = *pphead;while (prev->next!=pos)//找到pos的位置{prev = prev->next;//prev存放pos的地址}//找到位置SLTNode* newnode = BuySListNode(x);//创建新链表元素,并赋值prev->next = newnode;//给前一个元素赋上下一元素地址newnode->next = pos;//给插入元素存放下一个元素的地址}
}
删除pos位置的值
void SListErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead);assert(pos);if (*pphead == pos)SListPopFront(pphead);//头删else{SLTNode* prev = *pphead;while (prev->next != pos)//找到pos的位置{prev = prev->next;//prev存放pos的地址//移到pos前一位,next存放的是pos的地址}//将prev存放的地址改为pos后一个元素的地址prev->next = pos->next;//释放posfree(pos);pos = NULL;}
}
成品展示
SList.h
#pragma once#include <stdlib.h>
#include <stdio.h>
#include <assert.h>typedef int SLTDataType;typedef struct SListNode
{int data;struct SListNode* next;
}SLTNode;//打印链表
void SListPrint(SLTNode* phead);//创建新链表元素(动态申请一个节点)
SLTNode* BuySListNode(SLTDataType x);//尾插
void SListPushBack(SLTNode** pphead, SLTDataType x);//头插
void SListPushFront(SLTNode** pphead, SLTDataType x);//尾删
void SListPopBack(SLTNode** pphead);//头删
void SListPopFront(SLTNode** pphead);//查找->可在查找的基础上进行修改SListAlter
SLTNode* SListFind(SLTNode* phead,SLTDataType x);void SListAlter(SLTNode* phead, SLTDataType x,SLTDataType y);//pos位置之前插入
void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);//删除pos位置的值
void SListErase(SLTNode** pphead, SLTNode* pos);
SList.c
#include "SList.h"//打印
void SListPrint(SLTNode* phead)
{SLTNode* cur = phead;while (cur!=NULL){printf("%d->", cur->data);cur = cur->next;//存放下一个元素的地址}printf("NULL\n");
}//创建新链表元素
SLTNode* BuySListNode(SLTDataType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));assert(newnode);newnode->data = x;newnode->next = NULL;return newnode;
}//尾插
void SListPushBack(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = BuySListNode(x);//dataif (*pphead == NULL){//防止开始时节点为空*pphead = newnode;}else{//找尾节点SLTNode* tail = *pphead;while (tail->next != NULL){//存放新节点地址tail = tail->next;}tail->next = newnode;}
}//头插
void SListPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = BuySListNode(x);newnode->next = *pphead;*pphead = newnode;//地址传给pphead //*pphead=&plist/*头插无需检查是否为空*/
}//尾删
void SListPopBack(SLTNode** pphead)
{assert(*pphead);if ((*pphead)->next==NULL){//1,只有一个节点free(*pphead);*pphead = NULL;}else{//2,有多个节点//将前一个链元素中存放的地址换为NULL,防止野指针/* 写法一 */SLTNode* tailPrev = NULL;SLTNode* tail = *pphead;while (tail->next!=NULL){tailPrev = tail;//tail的地址tail = tail->next;}free(tail);tailPrev->next = NULL;/* //写法二* //tail寻找的是倒数第二个元素while (tail->next->next!=NULL){tail = tail->next;}free(tail->next);tail->next = NULL;*/}
}//头删
void SListPopFront(SLTNode** pphead)
{ //防止被删空assert(*pphead);SLTNode* next = (*pphead)->next;free(*pphead);*pphead = next;
}//查找-给一个节点的指针
SLTNode* SListFind(SLTNode* phead, SLTDataType x)
{SLTNode* cur = phead;while (cur){if (cur->data==x)return cur;cur = cur->next;}return NULL;
}//改
void SListAlter(SLTNode* phead, SLTDataType x, SLTDataType y)
{assert(phead);printf("修改成功:\n");SLTNode* ret = SListFind(phead, y);ret->data = x;
}
//pos位置之前插入
void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pphead);assert(pos);//头插if (pos == *pphead)SListPushFront(pphead, x);else{ SLTNode* prev = *pphead;while (prev->next!=pos)//找到pos的位置{prev = prev->next;//prev存放pos的地址}//找到位置SLTNode* newnode = BuySListNode(x);//创建新链表元素,并赋值prev->next = newnode;//给前一个元素赋上下一元素地址newnode->next = pos;//给插入元素存放下一个元素的地址}
}//删除pos位置的值
void SListErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead);assert(pos);if (*pphead == pos)SListPopFront(pphead);//头删else{SLTNode* prev = *pphead;while (prev->next != pos)//找到pos的位置{prev = prev->next;//prev存放pos的地址//移到pos前一位,next存放的是pos的地址}//将prev存放的地址改为pos后一个元素的地址prev->next = pos->next;//释放posfree(pos);pos = NULL;}
}
test.c
test.c仅仅是用于测试代码,本文以弄懂单向链表为主,故不进行菜单制作
但改测试中也包含了对部分链表结构即原理进行了讲解,请耐心看完
#include "SList.h"
void TestSList1()
{ SLTNode* n1 = (SLTNode*)malloc(sizeof(SLTNode));assert(n1);SLTNode* n2 = (SLTNode*)malloc(sizeof(SLTNode));assert(n2);SLTNode* n3 = (SLTNode*)malloc(sizeof(SLTNode));assert(n3);SLTNode* n4 = (SLTNode*)malloc(sizeof(SLTNode));assert(n4);n1->data=1;n2->data=2;n3->data=3;n4->data=4;n1->next = n2;n2->next = n3;n3->next = n4;n4->next = NULL;SListPrint(n1);
}void TestSList2()
{SLTNode* plist = NULL;//传的是plist指针的地址//如果直接传plist,将导致SLTNode* phead中//phead为临时拷贝,不影响实参SListPushBack(&plist, 1);SListPushBack(&plist, 2);SListPushBack(&plist, 3);SListPushBack(&plist, 4);SListPrint(plist);//不改变无需传二级指针SListPushFront(&plist,0);SListPrint(plist);SListPopFront(&plist);SListPrint(plist);SListPopBack(&plist);/*SListPrint(plist);SListPopBack(&plist);SListPrint(plist);SListPopBack(&plist);SListPrint(plist);SListPopBack(&plist);SListPrint(plist);*//*SListPopBack(&plist);SListPrint(plist);*/
}void TestSList3()
{SLTNode* plist = NULL;//传的是plist指针的地址//如果直接传plist,将导致SLTNode* phead中//phead为临时拷贝,不影响实参SListPushBack(&plist, 1);SListPushBack(&plist, 2);SListPushBack(&plist, 3);SListPushBack(&plist, 4);SListPrint(plist);//不改变无需传二级指针//查找SLTNode* ret = SListFind(plist, 3);if (ret){//返回值不为空则为找到printf("找到了\n");}SListPrint(plist);修改//SListAlter(plist, 20, 2);//SListPrint(plist);//插入SLTNode* pos = SListFind(plist, 3);//先要找到再进行更改if (pos){SListInsert(&plist, pos, 40);}SListPrint(plist);//删除pos = SListFind(plist, 2);//先要找到再进行删除if (pos){SListErase(&plist, pos);}SListPrint(plist);
}int main()
{TestSList3();return 0;
}
单向链表讲解完毕啦!创作不易,如果喜欢请留下个赞吧,感激不尽😊
相关文章:

数据结构:线性表之-单向链表(无头)
目录 什么是单向链表 顺序表和链表的区别和联系 顺序表: 链表: 链表表示(单项)和实现 1.1 链表的概念及结构 1.2单链表(无头)的实现 所用文件 将有以下功能: 链表定义 创建新链表元素 尾插 头插 尾删 头删 查找-给一个节点的…...

为IT服务台构建自定义Zia操作
Zia是manageengine的商业人工智能助手,是ServiceDesk Plus Cloud的虚拟会话支持代理。使用Zia,您可以优化帮助台管理,还可以缩小最终用户与其帮助台之间的差距,Zia通过执行预配置的操作来帮助用户完成他们的服务台任务。 例如&…...
【C/C++】BMP格式32位转24位
问题 如题 解决方法 bmp文件格式参考:【C/C++】BITMAP格式分析_vc++ bitmap头文件_sunriver2000的博客-CSDN博客BITMAP文件大体上分成四个部分,如下表所示。文件部分长度(字节)位图文件头 Bitmap File Header14位图信息数据头 Bitmap Info Header40调色板 Palette4*n (n≥…...

合宙Air724UG LuatOS-Air LVGL API控件-滑动条 (Slider)
滑动条 (Slider) 滑动条看起来和进度条是有些是有些像,但不同的是滑动条可以进行数值选择。 示例代码 -- 回调函数 slider_event_cb function(obj, event)if event lvgl.EVENT_VALUE_CHANGED then local val (lvgl.slider_get_value(obj) or "0")..&…...

SQLAlchemy 封装的工具类,数据库pgsql(数据库连接池)
1.SQLAlchemy是什么? SQLAlchemy 是 Python 著名的 ORM 工具包。通过 ORM,开发者可以用面向对象的方式来操作数据库,不再需要编写 SQL 语句。 SQLAlchemy 支持多种数据库,除 sqlite 外,其它数据库需要安装第三方驱动。…...

【Git】Git 基础
Git 基础 参考 Git 中文文档 — https://git-scm.com/book/zh/v2 1.介绍 Git 是目前世界上最先进的分布式版本控制系统,有这么几个特点: 分布式:是用来保存工程源代码历史状态的命令行工具保存点:保存点可以追溯源码中的文件…...

腾讯云AI绘画:探究AI创意与技术的新边界
目录 一、2023的“网红词汇”——AI绘画二、智能文生图1、智能文生图的应用场景2、风格和配置的多样性3、输入一段话,腾讯云AI绘画给你生成一张图4、文本描述生成图像,惊艳全场 三、智能图生图:重新定义图像美学1、智能图生图的多元应用场景2…...

离线数仓同步数据1
用户行为表数据同步 2.1.4 日志消费Flume测试 [gpbhadoop104 ~]$ cd /opt/module/flume/ [gpbhadoop104 flume]$ cd job/ [gpbhadoop104 job]$ rm file_to_kafka.confcom.atguigu.gmall.flume.interceptor.TimestampInterceptor$Builder #定义组件 a1.sourcesr1 a1.channelsc1…...

c语言开篇---跟着视频学C语言
标识符 标识符必须声明定义,可以是变量、函数或其他实体。 Int是标识符吗? 不是,int是c语言关键词,不是随意命名的 C语言关键词如下: 常量 不需要被声明,不能赋值更改。 printf函数 printf是由print打印…...

本地yum源-如学
学不学? 如学~ 到底学不学? 如学~ 学? 如学~ 配置本地的镜像yum 使用到的 rpm 包 是根据centos8 里面自带的 在 /dev/cdrom 中包含着 一些系统自带的 rpm # 先将 /dev/cdrom 设备进行挂载 mkdir /up # 在…...

【实训】“宅急送”订餐管理系统(程序设计综合能力实训)
👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》 🌝每一个不曾起舞的日子,都是对生命的辜负 前言 大一小学期,我迎来了人生中的第一次实训…...

openeuler上安装polarismesh集群
1、安装MySQL数据库 数据库连接地址10.10.10.168 用户root 密码123456 MySQL安装参考搭建DSS环境(六)之安装基础环境MySQL_linux安装dss_青春不流名的博客-CSDN博客 2、安装Redis集群 IPResid PORTSentinel PORTPASSWORDCluster NAME10.10.10.110637…...

Java基础——stream
流 stream是什么?stream优点stream和集合的区别stream的创建steam的操作从steam中取值 stream是什么? stream可以简化对集合的操作,具体操作由流内部实现,而无需用户自行实现过程 stream优点 对于以下ArrayList List<Strin…...

Spring Quartz 持久化解决方案
Quartz是实现了序列化接口的,包括接口,所以可以使用标准方式序列化到数据库。 而Spring2.5.6在集成Quartz时却未能考虑持久化问题。 Spring对JobDetail进行了封装,却未实现序列化接口,所以持久化的时候会产生NotSerializable问题&…...

基于Java+SpringBoot+Vue前后端分离火锅店管理系统设计和实现
博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…...

Unity——导航系统补充说明
一、导航系统补充说明 1、导航与动画 我们可以通过设置动画状态机的变量,让动画匹配由玩家直接控制的角色的移动。那么自动导航的角色如何与动画系统结合呢? 有两个常用的属性可以获得导航代理当前的状态: 一是agent.velocity,…...

nginx实现负载均衡load balance
目录 nginx实现负载均衡load balance相关算法负载均衡https的访问后端的real server是否知道真正访问的用户的IP地址健康检查提升负载均衡的并发数量七层负载均衡和四层负载均衡七层负载均衡四层负载均衡四层和七层的区别502错误 nginx实现负载均衡load balance 准备ÿ…...

淘宝订单接口:连接消费者与商家的桥梁
当我们谈论淘宝订单接口时,我们谈论的是淘宝网为卖家和买家提供的一个用于处理订单的核心系统。通过这个接口,卖家可以接收订单、处理订单状态,并更新买家和平台的状态信息;买家则可以实时追踪自己的订单状态,更好地掌…...

数据结构-第一期——数组(Python)
目录 00、前言: 01、一维数组 一维数组的定义和初始化 一维变长数组 一维正向遍历 一维反向遍历 一维数组的区间操作 竞赛小技巧:不用从a[0]开始,从a[1]开始 蓝桥杯真题练习1 读入一维数组 例题一 例题二 例题三 实战训…...

八 动手学深度学习v2 ——卷积神经网络之卷积+填充步幅+池化+LeNet
目录 1. 图像卷积总结2. 填充和步幅 padding和stride3. 多输入多输出通道4. 池化层5. LeNet 1. 图像卷积总结 二维卷积层的核心计算是二维互相关运算。最简单的形式是,对二维输入数据和卷积核执行互相关操作,然后添加一个偏置。核矩阵和偏移是可学习的参…...

SparkCore
第1章 RDD概述 1.1 什么是RDD RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象。代码中是一个抽象类,它代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合。 RDD类比工厂生产。 …...

配置 Windows 系统环境变量
直接按键盘上面的 WINS 打开 Windows 搜索 搜索“编辑系统环境变量” 也可以右键此电脑->属性->高级系统设置打开相同的界面 点击环境变量 一般添加就是添加在框出的 Path 里面,双击可以看到现有的环境变量并进行编辑 例如我在博客中写把 Java 的 jdk 解压好…...

【计算机视觉】图片文件格式的讲解
文章目录 一、图片的压缩二、计算机表示颜色三、JPG和PNG3.1 JPG3.2 PNG 一、图片的压缩 图片文件格式有可能会对图片的文件大小进行不同程度的压缩,图片的压缩分为有损压缩和无损压缩两种。 有损压缩。指在压缩文件大小的过程中,损失了一部分图片的信…...

2023最全的性能测试种类介绍,这6个种类特别重要!
系统的性能是一个很大的概念,覆盖面非常广泛,包括执行效率、资源占用、系统稳定性、安全性、兼容性、可靠性、可扩展性等,性能测试就是描述测试对象与性能相关的特征并对其进行评价而实施的一类测试。 性能测试是一个统称,它其实包…...

代码随想录算法训练营19期第43天
1049. 最后一块石头的重量 II 视频讲解:动态规划之背包问题,这个背包最多能装多少?LeetCode:1049.最后一块石头的重量II_哔哩哔哩_bilibili 代码随想录 初步思路:动态规划。 总结:套用01背包 dp[j…...

微信小程序wx.previewImage实现图片预览
在微信小程序中,wx.previewImage函数用于预览图片,可以将一组图片以轮播的方式展示给用户,并支持用户手势操作进行切换。 使用wx.previewImage函数需要传入一个参数对象,该对象包含以下属性: current: String&#x…...

Java实现Modbus读写数据
背景 由于当时项目周期赶,引入了一个PLC4X组件,上手快。接下来就是使用这个组件遇到的一些问题: 关闭连接NioEventLoop没有释放导致oom设计思想是一个设备一个连接,而不是一个网关一个连接连接断开后客户端无从感知 前两个问题解…...

C++11新特性⑤ | 仿函数与lambda表达式
目录 1、引言 2、仿函数 3、lambda表达式 3.1、lambda表达式的一般形式 3.2、返回类型说明 3.3、捕获列表的规则 3.4、可以捕获哪些变量 3.5、lambda表达式给编程带来的便利 VC常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...&a…...

解决websocket不定时出现1005错误
后台抛出异常如下: Operator called default onErrorDropped reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IllegalArgumentException: WebSocket close status code does NOT comply with RFC-6455: 1005 Caused by: java.lang.IllegalArgume…...

文章内容生成随机图像,并将这些图像上链
一、需求背景 在当前的互联网时代,信息越来越快速地传播,一篇好的文章不仅需要有吸引人的文字内容,还需要有精美的配图。但是,对于某些只有文字,而没有图片的文章,我们可以使用程序去生成随机的图片来作为文章的配图。 本文将详细介绍如何使用Java语言实现文章内容生成…...