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

在这里插入图片描述

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

🍋单链表

  • 🍌单链表的定义
  • 🍌单链表的结构
    • 🍍循环的单链表
    • 🍍不循环单链表
  • 🍌单链表增删查改(无头+单向+非循环链表增删查改实现)
    • 🍍其它接口
    • 🍍动态申请一个节点
    • 🍍单链表打印
    • 🍍单链表尾插
    • 🍍单链表的头插
    • 🍍单链表的尾删
    • 🍍单链表头删
    • 🍍单链表查找
    • 🍍单链表在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.rhkb.cn/news/201195.html

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

相关文章

PostgreSQL导出表结构带注释

我们在平时开发过程中&#xff0c;经常会在字段的注释中&#xff0c;加上中文&#xff0c;解释字段的相关含义&#xff0c;也可以避免时间太久忘记这个字段代表什么&#xff0c;毕竟英文水平不好。我们可能要经常整理数据库表结构&#xff0c;提供他人去收集数据&#xff0c;但…

【SpringBoot】通过profiles设置环境

效果图&#xff0c;通过profiles设置环境 在父级pom.xml中添加配置 <profiles><profile><id>dev</id><properties><application.environment>dev</application.environment></properties><activation><activeByDefau…

前端数组方法汇总集锦

前言 数组主要使用场景有&#xff1a; 存储和处理数据&#xff1a;数组是一种有序的数据结构&#xff0c;可以用来存储和处理多个相关的数据。在前端开发中&#xff0c;我们经常使用数组来存储和处理列表、表格、选项等数据。 循环和遍历&#xff1a;数组提供了循环和遍历的功能…

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; 依赖属性的名称。在…

CmakeLists编译的动态库.so移动到其他位置后,提示找不到该库的依赖库解决办法

主要问题&#xff1a; 最近在搞海康SDK调用相机&#xff0c;发现在linux下一直调用不起来相机&#xff0c;总是提示error code&#xff1a;29&#xff0c;注册失败&#xff0c;重新编译优惠存在找不到依赖库的问题。 1.异常 CmakeLists编译的动态库.so移动到其他位置后&#…

【擎标】CCID信息系统服务商交付能力等级认证标准

为顺应信息技术服务业发展趋势及市场需求&#xff0c;维护市场秩序&#xff0c;加强行业自律&#xff0c;促进信息系统服务商交付能力的不断提高&#xff0c;增强信息系统服务商创新能力和国际竞争力&#xff0c;支撑信息系统服务商转型提升&#xff0c;中国软件行业协会、企业…

Python (十二) 文件

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

CCFCSP试题编号:201912-2试题名称:回收站选址

这题只要比较坐标的四周&#xff0c;然后计数就可以了。 #include <iostream> using namespace std;int main() {int n;cin >> n;int arr[1005][2] { 0 };int res[5] { 0 };int up 0;int down 0;int left 0;int right 0;int score 0;for (int i 0; i <…

矩阵运算_矩阵的协方差矩阵/两个矩阵的协方差矩阵_求解详细步骤示例

1. 协方差矩阵定义 在统计学中&#xff0c;方差是用来度量单个随机变量的离散程度&#xff0c;而协方差则一般用来刻画两个随机变量的相似程度。 参考&#xff1a; 带你了解什么是Covariance Matrix协方差矩阵 - 知乎 2. 协方差矩阵计算过程 将输入数据A进行中心化处理得到A…

移远通信推出六款新型天线,为物联网客户带来更丰富的产品选择

近日&#xff0c;移远通信重磅推出六款新型天线&#xff0c;覆盖5G、非地面网络&#xff08;NTN&#xff09;等多种新技术&#xff0c;将为物联网终端等产品带来全新功能和更强大的连接性能。 移远通信COO张栋表示&#xff1a;“当前&#xff0c;物联网应用除了需要高性能的天线…

JOSEF信号继电器 JX-18A/2 电压 220VAC辅助电源 板后接线

JX-18/2A系列信号继电器 JX-18A/2A1信号继电器&#xff1b; JX-18A/2A2信号继电器&#xff1b; JX-18B /2A1信号继电器; JX-18B/2A2信号继电器; JX-18C/2A1信号继电器; JX-18C/2A2信号继电器; JX-18E/2A1信号继电器; JX-18E/2A2信号继电器; JX-18D/2A1信号继电器; JX…

【计算机方向】通信、算法、自动化、机器人、电子电气、计算机工程、控制工程、计算机视觉~~~~~合集!!!

◆本文为大家梳理了近期可投的EI国际会议&#xff0c;涵盖计算机各个学科方向&#xff0c;均可EI检索 本期EI会议汇总合集涵盖领域&#xff1a;计算机视觉、物联网、算法、通信、智能技术、人工智能、人机交互、机器人、电子电气等众多领域&#xff01; 本期所推荐的EI会议有…

java:application.properties的详细使用以及区分环境

文章目录 什么是application.properties文件&#xff1f;如何在Java中使用application.properties文件&#xff1f;将数据注入到 Bean 中使用自定义的配置文件使用命令行参数进行配置配置文件的优先级加载外部的配置文件多环境配置1、创建配置文件2、在 application.properties…

RabbitMQ消息队列快速入门

RabbitMQ消息队列快速入门 初始MQ MQ全称为Message Queue&#xff0c;即消息队列&#xff0c;是在消息的传输过程中保存消息的容器。它是典型的生产者-消费者模型。 生产者不断向消息队列中生产消息&#xff0c;消费者不断的从队列中获取消息。消息的生产和消费都是异步的&am…

Windows本地搭建rtmp推流服务

前言 开发时偶尔需要使用rtmp直播流做视频流测试&#xff0c;苦于网上开源的rtmp视频流都已经失效&#xff0c;无奈只好尝试在本地自己搭建一个rtmp的推流服务&#xff0c;方便测试使用。 一、工具准备 Nginx&#xff1a;使用nginx-rtmp-win64推流工具FFmpeg&#xff1a;官方…

上海亚商投顾:北证50指数大涨 机器人概念股掀涨停潮

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日震荡反弹&#xff0c;黄白二线有所分化&#xff0c;题材热点轮动表现。北证50指数大涨超3%&#…

劲松HPV防治诊疗中心提醒:做完HPV检查后,需留意这些事项!

在接受HPV检查后&#xff0c;有一些注意事项需要您注意。首先&#xff0c;要遵循医生的建议&#xff0c;并按照医生的指示进行后续治疗和随访。 其次&#xff0c;检查后可能会有些不适感&#xff0c;这是正常的现象&#xff0c;不必过于担心。但是&#xff0c;如果不适感持续加…

产品工程师工作的职责十篇(合集)

一、岗位职责的作用意义 1.可以最大限度地实现劳动用工的科学配置; 2.有效地防止因职务重叠而发生的工作扯皮现象; 3.提高内部竞争活力&#xff0c;更好地发现和使用人才; 4.组织考核的依据; 5.提高工作效率和工作质量; 6.规范操作行为; 7.减少违章行为和违章事故的发生…

9. BeanFactory 和 ApplicationContext有什么区别?

BeanFactory 和 ApplicationContext有什么区别&#xff1f; BeanFactory和ApplicationContext是Spring的两大核心接口&#xff0c;都可以当做Spring的容器。其中ApplicationContext是 BeanFactory的子接口。 依赖关系 BeanFactory&#xff1a;是Spring里面最顶层的接口&#…