单链表(数据结构与算法)

在这里插入图片描述

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿
🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟
🌟🌟 追风赶月莫停留 🌟🌟
🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀
🌟🌟 平芜尽处是春山🌟🌟
🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟
🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅

🍋单链表

  • 🍌单链表的定义
  • 🍌单链表的结构
    • 🍍循环的单链表
    • 🍍不循环单链表
  • 🍌单链表增删查改(无头+单向+非循环链表增删查改实现)
    • 🍍其它接口
    • 🍍动态申请一个节点
    • 🍍单链表打印
    • 🍍单链表尾插
    • 🍍单链表的头插
    • 🍍单链表的尾删
    • 🍍单链表头删
    • 🍍单链表查找
    • 🍍单链表在pos位置之后插入x
    • 🍍 单链表删除pos位置之后的值
  • 🍌单链表整体代码的实现

🍌单链表的定义

单链表:一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

在这里插入图片描述

上图就是一个简单的空的(没有装数据)单链表

🍌单链表的结构

🍍循环的单链表

typedef int SLDatatype;
typedef struct SListNode
{SLDatatype val;struct SListNode* next;}SListNode;

在这里插入图片描述

这就是循环的单链表

🍍不循环单链表

typedef int SLDatatype;
typedef struct SListNode
{SLDatatype val;struct SListNode* next;}SListNode;

在这里插入图片描述

这就是不循环的单链表,而且没有装入数据

循环单链表和不循环的单链表创建是一样的只不过是在结尾的时候,循环的单链表中最后一个也就是尾指向了头,而不循环的单链表中的尾指向了空(NULL)

🍌单链表增删查改(无头+单向+非循环链表增删查改实现)

🍍其它接口

#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>typedef int SLDatatype;
typedef struct SListNode
{SLDatatype val;struct SListNode* next;}SListNode;

🍍动态申请一个节点

// 动态申请一个节点
SListNode* BuySListNode(SLDatatype x)
{SListNode* cur = (SListNode*)malloc(sizeof(SListNode));if (cur == NULL){perror("malloc  faild");exit(-1);}cur->val = x;cur->next = NULL;return cur;
}

大家如果对于malloc和realloc以及空间的创建的用法有些遗忘,可以看我这篇博客:动态内存管理(这是一个链接,有需要的朋友可以直接点进去)

🍍单链表打印

// 单链表打印
void SListPrint(SListNode* ps)
{//为保存头指针的位置//需要重新定义一个指针来移动SListNode* cur = ps;    while (cur){printf("%d->", cur->val);cur = cur->next;}printf("NULL\n");
}

因为在链表这里,都是指针移动,所以我们需要保存头指针的位置不变,故需要重新定义一个指针来移动。

🍍单链表尾插

// 单链表尾插
void SListPushBack(SListNode** ps, SLDatatype x)
{SListNode* new = BuySListNode(x);//尾插要分两种情况//第一种是链表里是为空的,而为空,就需要用到二级指针来改变结构体的指针//第二种是链表里数据不为空的
if (*ps == NULL){*ps = new;}else{SListNode* cur = *ps;while (cur->next != NULL){cur = cur->next;}cur->next = new;}
}

注意
尾插要分两种情况
(1)第一种是链表里是为空的,而为空,就需要用到二级指针来改变结构体的指针
(2)第二种是链表里数据不为空的

在这里插入图片描述

大家可能对于这个没有头的头指针还是难以理解,尽可能去理解吧,我刚开始学习这个也是这样,不过单链表题写多了以及学了后面带头的头指针就会好很多。

在这里插入图片描述

第二种情况还是很好理解的

🍍单链表的头插

// 单链表的头插第一种方法:
void SListPushFront(SListNode** ps, SLDatatype x)
{SListNode* new = BuySListNode(x);if (*ps == NULL){*ps = new;}else{SListNode* cur = *ps;*ps = new;new->next = cur;}
}
// 单链表的头插第二种方法:
void SListPushFront(SListNode** ps, SLDatatype x)
{SListNode* new = BuySListNode(x);new->next = *ps;*ps = new;}

在这里插入图片描述

在这里插入图片描述

这两种方法都挺好理解的

🍍单链表的尾删

// 单链表的尾删
void SListPopBack(SListNode** ps)
{assert(*ps);//防止链表为空if ((*ps)->next == NULL)//只有一个节点{free(*ps);*ps = NULL;}else                    //两个节点及以上{SListNode* cur = *ps;while (cur->next->next != NULL){cur = cur->next;}free(cur->next); cur->next = NULL;}
}

注意节点个数
在尾删就得看节点个数了,然后分为三种情况,0节点和一个节点、两个节点及以上

在这里插入图片描述

🍍单链表头删

// 单链表头删
void SListPopFront(SListNode** ps)
{assert(*ps);//防止链表为空//链表不为空SListNode* cur = *ps;*ps = cur->next;free(cur);cur->next = NULL;
}

在这里插入图片描述

上面的尾插,头插,尾删,了解后,这里应该都能很好的理解了

🍍单链表查找

// 单链表查找
SListNode* SListFind(SListNode* ps, SLDatatype x)
{assert(ps);SListNode* cur = ps;while (cur->next != NULL){if (cur->val == x){return cur;}cur = cur->next;}return NULL;
}

这个查找就很简单了,直接遍历一遍就可以了,注意一下循环停止的时间

🍍单链表在pos位置之后插入x

// 单链表在pos位置之后插入x
void SListInsertAfter(SListNode* pos, SLDatatype x)
{assert(pos);SListNode* cur = pos->next;SListNode* new = BuySListNode(x);if (new == NULL){perror("malloc   faild");exit(-1);}pos->next = new;new->next = cur;}

🍍 单链表删除pos位置之后的值

// 单链表删除pos位置之后的值
void SListEraseAfter(SListNode* pos)
{assert(pos);assert(pos->next);  //检查是否是尾节点SListNode* cur = pos->next;pos->next = cur->next;free(cur);cur = NULL;
}

在这里注意一下pos是否为尾节点

🍌单链表整体代码的实现

#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>typedef int SLDatatype;
typedef struct SListNode
{SLDatatype val;struct SListNode* next;}SListNode;// 动态申请一个节点
SListNode* BuySListNode(SLDatatype x)
{SListNode* cur = (SListNode*)malloc(sizeof(SListNode));if (cur == NULL){perror("malloc  faild");exit(-1);}cur->val = x;cur->next = NULL;return cur;
}// 单链表打印
void SListPrint(SListNode* ps)
{SListNode* cur = ps;while (cur){printf("%d->", cur->val);cur = cur->next;}printf("NULL\n");
}// 单链表尾插
void SListPushBack(SListNode** ps, SLDatatype x)
{SListNode* new = BuySListNode(x);if (*ps == NULL){*ps = new;}else{SListNode* cur = *ps;while (cur->next != NULL){cur = cur->next;}cur->next = new;}
}// 单链表的头插
void SListPushFront(SListNode** ps, SLDatatype x)
{第一种方法://SListNode* new = BuySListNode(x);//if (*ps == NULL)//{//	*ps = new;//}//else//{//	SListNode* cur = *ps;//	*ps = new;//	new->next = cur;//}//第二种方法:SListNode* new = BuySListNode(x);new->next = *ps;*ps = new;}// 单链表的尾删
void SListPopBack(SListNode** ps)
{assert(*ps);//防止链表为空if ((*ps)->next == NULL)//只有一个节点{free(*ps);*ps = NULL;}else                    //两个节点及以上{SListNode* cur = *ps;while (cur->next->next != NULL){cur = cur->next;}free(cur->next); cur->next = NULL;}
}// 单链表头删
void SListPopFront(SListNode** ps)
{assert(ps);assert(*ps);//防止链表为空//链表不为空SListNode* cur = *ps;*ps = cur->next;free(cur);cur = NULL;
}// 单链表查找
SListNode* SListFind(SListNode* ps, SLDatatype x)
{assert(ps);SListNode* cur = ps;while (cur){if (cur->val == x){return cur;}cur = cur->next;}return NULL;
}// 单链表在pos位置之后插入x
void SListInsertAfter(SListNode* pos, SLDatatype x)
{assert(pos);SListNode* cur = pos->next;SListNode* new = BuySListNode(x);if (new == NULL){perror("malloc   faild");exit(-1);}pos->next = new;new->next = cur;}// 单链表删除pos位置之后的值
void SListEraseAfter(SListNode* pos)
{assert(pos);assert(pos->next);  //检查是否是尾节点SListNode* cur = pos->next;pos->next = cur->next;free(cur);cur = NULL;
}void test1()
{int n = 0;SListNode* plist = NULL;SListPushBack(&plist, 100);//尾插SListPushBack(&plist, 200);//尾插SListPushBack(&plist, 300);//尾插SListPushBack(&plist, 400);//尾插SListPrint(plist);//打印SListPushFront(&plist, 900);//头插SListPushFront(&plist, 800);//头插SListPushFront(&plist, 700);//头插SListPushFront(&plist, 600);//头插SListPrint(plist);//打印SListPopBack(&plist);//尾删SListPrint(plist);//打印SListPopFront(&plist);//头删SListPrint(plist);//打印SListNode* pos = SListFind(plist, 200);//查找if (pos != NULL){printf("找到了\n");}else{printf("找不到\n");}SListInsertAfter(pos, 999);//在pos位置之后插入xSListPrint(plist);SListEraseAfter(pos);//删除pos位置之后的值SListPrint(plist);
}int main()
{test1();return 0;
}

传地址的时候注意:有一些函数只需要传一级指针就可以了,而有些函数需要传二级指针。在这里一级指针直接传结构体就可以了,这是因为我们定义的是指针的结构体,而二级指针就需要传结构体的地址了。

请添加图片描述

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

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

相关文章

口袋参谋:只用一招,提前规避差评!请看具体操作步骤

​如何提前规避差评&#xff1f;至少99%的商家都不知道该怎么做&#xff0c;剩下的1%还是我刚教会的。 宝贝的评价直接影响宝贝转化&#xff0c;特别是新品链接。 10个好评也挽回不了一个差评对产品的致命打击&#xff0c;差评就像一个重磅炸弹&#xff0c;威力足够能让你的转…

RabbitMQ安装说明

注意: 本次安装以 CentOS 7为例 1、 准备软件 erlang 18.3 1.el7.centos.x86_64.rpm socat 1.7.3.2 5.el7.lux.x86_64.rpm rabbitmq server 3.6.5 1.noarch.rpm 2、安装Erlang rpm -ivh erlang-18.3-1.el7.centos.x86_64.rpm 3.、安装RabbitMQ 安装 rpm -ivh socat-1.7.3.2-…

2.4G无线收发芯片 XL2400P使用手册

XL2400P 系列芯片是工作在 2.400~2.483GHz 世界通用 ISM 频段的单片无线收发芯片。该芯片集成射 频收发机、频率收生器、晶体振荡器、调制解调器等功能模块&#xff0c;并且支持一对多组网和带 ACK 的通信模 式。发射输出功率、工作频道以及通信数据率均可配置。芯片已将多颗外…

深眸科技以自研算法+先进硬件,创新打造AI视觉一体化解决方案

工业视觉软硬件一体化解决方案&#xff1a;是以工业AI视觉技术为核心&#xff0c;通过集成工业相机等视觉硬件、电控系统和机械系统等自动化设备以及算法平台等软件应用&#xff0c;为工业自动化降本增效提质。 深眸科技为进一步巩固和加强技术领先优势&#xff0c;创新打造的…

【精选】构建智能木材计数系统:深度学习与OpenCV完美结合(详细教程+源码)

1.研究背景与意义 随着科技的不断发展&#xff0c;计算机视觉技术在各个领域中得到了广泛的应用。其中&#xff0c;卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;作为一种强大的深度学习模型&#xff0c;已经在图像识别、目标检测、人脸识…

鸿蒙原生应用/元服务开发-AGC分发如何编译打包应用

软件包规范 在正式打包应用前&#xff0c;请确保已了解HarmonyOS应用软件包规范。 操作步骤 1.打开DevEco Studio&#xff0c;菜单选择“Build > Build Hap(s)/APP(s) > Build APP(s)”。 2.等待编译构建。编译完成后&#xff0c;将在工程目录“build > outputs >…

vr编辑器可以解决教育教学中的哪些问题

VR编辑器是一种基于虚拟现实技术的教育内容编辑器&#xff0c;可以帮助教师快速创建出高质量的虚拟现实教学内容。 比如在畜牧教学类&#xff0c;通过这个软件&#xff0c;教师可以将真实的动物场景、行为和特征模拟到虚拟现实环境中&#xff0c;让学生在沉浸式的体验中学习动物…

D-Wave推出新开源及解决无线信道解码新方案!

​&#xff08;图片来源&#xff1a;网络&#xff09; 加拿大量子计算机公司D-Wave&#xff08;纽约证券交易所股票代码&#xff1a;QBTS&#xff09;是量子计算系统、软件和服务领域的佼佼者&#xff0c;也是全球首家商业量子计算机供应商。 近期&#xff0c;该公司发布了一…

LangChain: 类似 Flask/FastAPI 之于 Django,LangServe 就是「LangChain 自己的 FastAPI」

原文&#xff1a;LangChain: 类似 Flask/FastAPI 之于 Django&#xff0c;LangServe 就是「LangChain 自己的 FastAPI」 - 知乎 说明&#xff1a;LangServe代替 langchainserver 成为新的langchain 部署工具 官网资料&#xff1a;&#x1f99c;️&#x1f3d3; LangServe | &…

【SpringBoot】ThreadLocal 的详解

一、ThreadLocal 简介 ThreadLocal 叫做线程变量&#xff0c;意思是 ThreadLocal 中填充的变量属于当前线程&#xff0c;该变量对其他线程而言是隔离的&#xff0c;也就是说该变量是当前线程独有的变量。ThreadLocal 为变量在每个线程中都创建了一个副本&#xff0c;那么每个线…

企业如何选择一款高效的ETL工具

企业如何选择一款高效的ETL工具? 在企业发展至一定规模后&#xff0c;构建数据仓库&#xff08;Data Warehouse&#xff09;和商业智能&#xff08;BI&#xff09;系统成为重要举措。在这个过程中&#xff0c;选择一款易于使用且功能强大的ETL平台至关重要&#xff0c;因为数…

Android:Google三方库之Firebase集成详细步骤(一)

前提条件 安装最新版本的 Android Studio&#xff0c;或更新为最新版本。使用您的 Google 账号登录 Firebase请注意&#xff0c;依赖于 Google Play 服务的 Firebase SDK 要求设备或模拟器上必须安装 Google Play 服务 将Firebase添加到应用&#xff1a; 方式&#xff1a;使用…

智慧工地综合管理平台-环境监测子系统概要设计说明书

需求说明 原始背景 由于城市建设和工业化进程的加速,工地施工过程中的部分环节由于监管不到位,导致工地扬尘污染问题日益严重,对人类健康和环境质量造成了不可忽视的影响。为了解决这一问题,政府部门和相关企业逐渐意识到了建立工地扬尘监测系统的必要性和紧迫性,因此,环…

运行代码时不同软件的参数写法

目录 pycharm终端 pycharm 如下图所示&#xff0c;不同参数间不需要什么间隔什么东西 终端 如下图所示&#xff0c;不同参数间需要用一个符号来间隔

npm ERR!问题解决

问题一 解决办法 两个文件夹【node_global】和【node_cache】 修改文件属性 问题二 解决办法 安装淘宝镜像 npm config set registry https://registry.npm.taobao.org 查看是否成功&#xff1a; npm config get registry 是淘宝的就ok

腾讯三季度财报解读:AI大模型成下个十年的新支点?

2023年&#xff0c;腾讯重回高增长轨道。 近日&#xff0c;腾讯披露了2023年第三季度财报&#xff0c;营收1546.25亿元&#xff0c;同比增长10%&#xff1b;非国际通用会计准则下的净利润为449.21亿元&#xff0c;同比增长39%。此前两个季度&#xff0c;腾讯的营收、净利润增速…

DependencyProperty.Register:wpf 向别的xaml传递参数

一.使用背景&#xff1a;在A.xaml中嵌入B.xaml&#xff0c;并且向B.xaml传递参数。 函数介绍&#xff1a; public static DependencyProperty Register(string name, Type propertyType, Type ownerType );name&#xff08;string&#xff09;&#xff1a; 依赖属性的名称。在…

Tekton — 通过tekton-operator部署tekton组件

文章目录 版本信息部署准备安装卸载tekton组件 Tektoncd Operator 作为一个 Kubernetes 的扩展&#xff0c;可以方便快捷地在 Kubernetes 集群上安装、升级和管理 Tekton Pipelines、Dashboard、Triggers 等组件。 那么本篇文章介绍在K8S集群中如何通过tekton-operator部署Tekt…

SAE 2.0,让容器化应用开发更简单

云布道师 云原生这个概念从提出&#xff0c;到壮大&#xff0c;再到今天的极大普及&#xff0c;始终处于一个不断演进和革新的过程中。云原生体系下应用的托管形态是随着企业应用架构在不断演进的。最早的应用大多是集中式、单体式的&#xff0c;应用通过优雅的分层来实现领域…

七牛云产品使用介绍之Kodo篇

前不久刚参加完七牛云举办的第二届1024创作节&#xff08;虽然只是我单方面的被各方大佬碾压&#xff09; 赛题是网页短视频应用开发&#xff0c;要求作品中使用七牛云的相关产品&#xff0c;于是我决定分享下七牛云产品的使用&#xff08;这么好用的产品很难忍住不想分享的心情…