【数据结构】单链表专题-->单链表实现(附:全部码源)

 🔥博客主页🔥:【 坊钰_CSDN博客 】

欢迎各位点赞👍评论✍收藏⭐

目录

1. 链表的概念及结构

2. 预前准备

2.1 分文件存放

 3. 单链表的实现

3.1 定义节点

3.2 尾插和头插

3.2.1 尾插

3.2.2 头插

3.3 节点申请空间和打印

3.3.1 节点申请空间

3.3.2 打印

3.4 尾删和头删

3.4.1 尾删

3.4.2 头删

3.5 在指定位置(前/后)插入数据

3.5.1 在指定位置之后插入数据

3.5.2 在指定位置之前插入数据

3.6 查找

3.7 删除查找节点和链表销毁

3.7.1 删除查找节点

3.7.2 销毁链表

4. 全部码源

4.1 文件

4.2 文件

 4.3 test.c文件

 5. 运行效果

6. 小结


1. 链表的概念及结构

概念:链表是⼀种物理存储结构上⾮连续、⾮顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的

链表的结构跟火车车厢相似,在链表⾥,每节“⻋厢”是什么样的呢?

  1. 与顺序表不同的是,链表⾥的每节"⻋厢"都是独⽴申请下来的空间,我们称之为“结点/节点”
  2. 节点的组成主要有两个部分:当前节点要保存的数据和保存下⼀个节点的地址(指针变量)
  3. 图中指针变量plist保存的是第⼀个节点的地址,我们称plist此时“指向”第⼀个节点,如果我们希 望plist“指向”第⼆个节点时,只需要修改plist保存的内容为0x0012FFA0;

结合前⾯学到的结构体知识,我们可以给出每个节点对应的结构体代码:

假设当前保存的节点为整型:

struct SListNode
{int data; //节点数据 struct SListNode* next; //指针变量⽤保存下⼀个节点的地址 
};

给定的链表结构中,如何实现节点从头到尾的打印?

思考:当我们想保存的数据类型为字符型、浮点型或者其他⾃定义的类型时,该如何修改?

补充说明:

  1. 链式机构在逻辑上是连续的,在物理结构上不⼀定连续
  2. 节点⼀般是从堆上申请的
  3. 从堆上申请来的空间,是按照⼀定策略分配出来的,每次申请的空间可能连续,可能不连续 

2. 预前准备

2.1 分文件存放

Slist.h    ----------->单链表结构及函数声明
Slist.c    ----------->单链表的函数实现
test.c    -------------->代码测试

 

 3. 单链表的实现

3.1 定义节点

//定义节点结构typedef int SLTDataType;typedef struct SListNode
{SLTDataType data;struct SListNode* next;
}SLTNode;

3.2 尾插和头插

3.2.1 尾插

//尾插实现
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{SLTNode* newnode = SLTBuyNode(x);assert(pphead);if (*pphead == NULL){*pphead = newnode;}else{SLTNode* pure = *pphead;while (pure->next){pure = pure->next;}pure->next = newnode;}
}

3.2.2 头插

//头插实现
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);newnode->next = *pphead;*pphead = newnode;
}

3.3 节点申请空间和打印

3.3.1 节点申请空间

//节点申请空间实现
SLTNode* SLTBuyNode(SLTDataType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc");return 0;}newnode->data = x;newnode->next = NULL;return newnode;
}

3.3.2 打印

//打印实现
void SLTPrin(SLTNode* phead)
{SLTNode* pure = phead;while (pure){printf("%d->", pure->data);pure = pure->next;}printf("NULL\n");
}

3.4 尾删和头删

3.4.1 尾删

//尾删实现
void SLTPopBack(SLTNode** pphead)
{assert(pphead&&*pphead);if ((*pphead)->next==NULL){free(*pphead);*pphead = NULL;}else{SLTNode* pure = *pphead;SLTNode* cure = *pphead;while (cure->next){pure = cure;cure = cure->next;}pure->next = NULL;free(cure);cure = NULL;}
}

3.4.2 头删

//头删实现
void SLTPopFront(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* pure = (*pphead)->next;free(*pphead);*pphead = pure;
}

3.5 在指定位置(前/后)插入数据

3.5.1 在指定位置之后插入数据

//在指定位置之后插入数据实现
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);SLTNode* newnode = SLTBuyNode(x);newnode->next = pos->next;pos->next = newnode;
}

3.5.2 在指定位置之前插入数据

//在指定位置之前插入数据实现
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pphead && *pphead && pos);if (*pphead == pos){SLTPushFront(pphead, x);}else{SLTNode* newnode = SLTBuyNode(x);SLTNode* pure = *pphead;while (pure->next != pos){pure = pure->next;}pure->next = newnode;newnode->next = pos;}
}

3.6 查找

//查找实现
SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{SLTNode* pure = phead;while (pure){if (pure->data == x){return pure;}pure = pure->next;}return NULL;
}

3.7 删除查找节点和链表销毁

3.7.1 删除查找节点

//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead && *pphead && pos);if (*pphead == pos){SLTPopFront(pphead);}else{SLTNode* pure = *pphead;while (pure->next != pos){pure = pure->next;}pure->next = pos->next;free(pos);pos = NULL;}
}

3.7.2 销毁链表

//销毁链表实现
void SListDesTroy(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* pure = *pphead;while (pure){SLTNode* next = pure->next;free(pure);pure = next;}*pphead = NULL;
}

4. 全部码源

4.1 <Slist.h>文件

<Slist.h>文件

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int SLTDataType;//定义节点结构
typedef struct SListNode
{SLTDataType data;struct SListNode* next;
}SLTNode;//节点申请空间
SLTNode* SLTBuyNode(SLTDataType x);//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x);//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x);//打印
void SLTPrin(SLTNode* phead);//尾删
void SLTPopBack(SLTNode** pphead);//头删
void SLTPopFront(SLTNode** pphead);//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x);//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x);//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos);//销毁链表
void SListDesTroy(SLTNode** pphead);

4.2 <Slist.c>文件

<Slist.c>文件

#include "Slist.h"//节点申请空间实现
SLTNode* SLTBuyNode(SLTDataType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc");return 0;}newnode->data = x;newnode->next = NULL;return newnode;
}//尾插实现
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{SLTNode* newnode = SLTBuyNode(x);assert(pphead);if (*pphead == NULL){*pphead = newnode;}else{SLTNode* pure = *pphead;while (pure->next){pure = pure->next;}pure->next = newnode;}
}//头插实现
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);newnode->next = *pphead;*pphead = newnode;
}//打印实现
void SLTPrin(SLTNode* phead)
{SLTNode* pure = phead;while (pure){printf("%d->", pure->data);pure = pure->next;}printf("NULL\n");
}//尾删实现
void SLTPopBack(SLTNode** pphead)
{assert(pphead&&*pphead);if ((*pphead)->next==NULL){free(*pphead);*pphead = NULL;}else{SLTNode* pure = *pphead;SLTNode* cure = *pphead;while (cure->next){pure = cure;cure = cure->next;}pure->next = NULL;free(cure);cure = NULL;}
}//头删实现
void SLTPopFront(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* pure = (*pphead)->next;free(*pphead);*pphead = pure;
}//查找实现
SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{SLTNode* pure = phead;while (pure){if (pure->data == x){return pure;}pure = pure->next;}return NULL;
}//在指定位置之前插入数据实现
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pphead && *pphead && pos);if (*pphead == pos){SLTPushFront(pphead, x);}else{SLTNode* newnode = SLTBuyNode(x);SLTNode* pure = *pphead;while (pure->next != pos){pure = pure->next;}pure->next = newnode;newnode->next = pos;}
}//在指定位置之后插入数据实现
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);SLTNode* newnode = SLTBuyNode(x);newnode->next = pos->next;pos->next = newnode;
}//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead && *pphead && pos);if (*pphead == pos){SLTPopFront(pphead);}else{SLTNode* pure = *pphead;while (pure->next != pos){pure = pure->next;}pure->next = pos->next;free(pos);pos = NULL;}
}//销毁链表实现
void SListDesTroy(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* pure = *pphead;while (pure){SLTNode* next = pure->next;free(pure);pure = next;}*pphead = NULL;
}

 4.3 test.c文件

test.c文件

#include "Slist.h"void SLTCheek()
{SLTNode* slist = NULL;//尾插printf("插入1~6\n");SLTPushBack(&slist, 1);SLTPushBack(&slist, 2);SLTPushBack(&slist, 3);SLTPushBack(&slist, 4);SLTPushBack(&slist, 5);SLTPushBack(&slist, 6);SLTPrin(slist);打印//SLTPrin(slist);//头插printf("头插入100\n");SLTPushFront(&slist, 100);SLTPrin(slist);//尾删printf("尾部删除\n");SLTPopBack(&slist);SLTPrin(slist);//头删printf("头部删除\n");SLTPopFront(&slist);SLTPrin(slist);//查找SLTNode* find = SLTFind(slist, 3);//在指定位置之前插入数据printf("在3之前插入数据99\n");SLTInsert(&slist, find, 99);SLTPrin(slist);//在指定位置之后插入数据printf("在3之后插入数据100\n");SLTInsertAfter(find, 100);SLTPrin(slist);//删除pos点printf("删除3的节点\n");SLTErase(&slist,find);SLTPrin(slist);//销毁SListDesTroy(&slist);
}int main()
{SLTCheek();return 0;
}

 5. 运行效果

6. 小结

以上就是关于单链表的内容了,具体还需宝子们去实践,如果觉得该博客对你有用的话,希望一键三连,点个关注不迷路,谢谢支持!

 

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

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

相关文章

css多种布局方式

css多种布局方式 简介标准流布局&#xff08;主要依赖margin\padding&#xff09;浮动布局&#xff08;float&#xff09;定位布局&#xff08;position&#xff09;弹性布局&#xff08;flex&#xff09;网格布局&#xff08;grid&#xff09;多列布局&#xff08;column&…

05-13 周一 量化是什么

05-13 周一 量化是什么 时间版本修改人描述2024年5月13日11:27:25V0.1宋全恒新建文档2024年5月14日16:21:20V1.0宋全恒了解 简介 神经网络在运行时有较高的计算成本&#xff0c;而且随着大模型时代的到来&#xff0c;知识由一个巨大的LLM存储&#xff0c;为了获取知识&#xf…

web入门练手案例(一)

下面是一下web入门案例和实现的代码&#xff0c;带有部分注释&#xff0c;倘若代码中有任何问题或疑问&#xff0c;欢迎留言交流~ 新闻页面 案例描述&#xff1a; 互联网的发展使信息的传递变得方便、快捷&#xff0c;浏览新闻称为用户获取信息的重要渠道。下面将实现一个简…

原子学习笔记3——点亮 LED

一、应用层操控设备的两种方式 应用层如何操控底层硬件&#xff0c;同样也是通过文件 I/O 的方式来实现&#xff0c;设备文件便是各种硬件设备向应用层提供的一个接口&#xff0c;应用层通过对设备文件的 I/O 操作来操控硬件设备&#xff0c;譬如 LCD 显示屏、串口、按键、摄像…

论文阅读:Self-Consistency Improves Chain of Thought Reasoning in Language Models

思维链 prompt 与预训练的大型语言模型相结合&#xff0c;在复杂的推理任务上取得了令人鼓舞的结果。在本文中&#xff0c;作者提出了一种新的解码策略&#xff0c;即自我一致性&#xff08;self-consistency&#xff09;&#xff0c;以取代思维链 prompt 中使用的 naive 贪婪解…

25. K 个一组翻转链表 - 力扣(LeetCode)

基础知识要求&#xff1a; Java&#xff1a;方法、while循环、for循环、if else语句 Python&#xff1a; 方法、while循环、for循环、if else语句 题目&#xff1a; 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个…

x264 帧类型代价计算原理:slicetype_slice_cost 函数分析

x264 x264 是一个开源的视频编码库,它实现了H.264/AVC标准。H.264是一种广泛使用的压缩标准,用于视频流、视频下载、蓝光光盘以及许多其他形式的数字视频分发。x264 以其高压缩效率和良好的视频质量而著称,是许多视频编辑软件和视频播放器的默认编解码器。 以下是关于 x26…

随易周刊第006期 - 云梦秦简

&#x1f4e2; 随易周刊介绍 这是一个由 前端之虎陈随易 维护的周刊&#xff0c;将会分享笔者一周内的所见所闻。 写一篇周刊 搜集整理发布 需要数天&#xff0c;请尊重笔者的成果&#xff0c;可任意转载&#xff0c;但不要篡改内容。 如果你觉得周刊不错&#xff0c;可以给…

未来互联网:Web3的技术革新之路

引言 随着技术的不断发展和社会的日益数字化&#xff0c;互联网作为信息交流和社交媒介的重要平台已经成为我们生活中不可或缺的一部分。然而&#xff0c;传统的互联网架构在数据安全、隐私保护和去中心化等方面存在着诸多挑战。为了解决这些问题&#xff0c;Web3技术应运而生…

做抖店不能踩的几个坑,新手要照做,老玩家要听劝~

我是王路飞。 很多人都说抖店的运营很简单&#xff0c;选选品、对接一下达人&#xff0c;就可以坐等店铺出单了。 这话骗骗还没开店的小白也就得了&#xff0c;但凡做抖店超过一个月的&#xff0c;都不会相信这句话。 细心耐心是做抖店最基本的态度。 拿到一个好结果的前提…

nginx反向代理使用(详细版)

1. 下载nginx&#xff0c;解压&#xff1b;&#xff08;随便放在哪里&#xff09; 2. 在nginx-1.26.0文件夹下创建web文件夹&#xff0c;继续在web文件夹下创建abcd.test.cn文件夹&#xff08;文件夹的名字就叫abcd.test.cn&#xff09;&#xff1b; 3. 配置前端代理&#xff…

Ubuntu安装k8s集群

文章目录 Ubuntu安装k8s3台主机前置操作&#xff1a;3台主机k8s前置安装命令&#xff1a;k8s安装命令&#xff1a; 节点加入 Ubuntu安装k8s 官方文档&#xff1a;https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/kubeadm/install-kubeadm/ 默认3台机子 注…

软件项目验收第三方测试报告如何获取

软件项目验收第三方测试报告是确保软件质量、安全性和稳定性的重要环节。对于企业和开发者来说&#xff0c;获取一份全面、专业的第三方测试报告&#xff0c;对于提升软件产品的竞争力和用户满意度至关重要。本文将介绍如何获取软件项目验收第三方测试报告&#xff0c;以及相关…

1Panel应用推荐:Uptime Kuma

1Panel&#xff08;github.com/1Panel-dev/1Panel&#xff09;是一款现代化、开源的Linux服务器运维管理面板&#xff0c;它致力于通过开源的方式&#xff0c;帮助用户简化建站与运维管理流程。为了方便广大用户快捷安装部署相关软件应用&#xff0c;1Panel特别开通应用商店&am…

在 CSS 中使用 text-emphasis 来增强文本的趣味性

在CSS中设置文本样式的方法有很多。您可以更改颜色、大小、字体&#xff0c;甚至添加阴影和轮廓等效果。但最近&#xff0c;我了解到一个我以前没有听说过的时尚 CSS 属性&#xff0c;它非常棒&#xff01; 它被称为文本强调&#xff08;text-emphasis&#xff09;&#xff0c…

什么是RSocket?它有哪些优势?

在传统Web应用开发过程中&#xff0c;我们都是基于HTTP协议实现请求-响应式的交互方式。这种交互方案很简单&#xff0c;但不够灵活&#xff0c;也无法应对所有的响应式应用场景。那么&#xff0c;有没有在网络协议层上提供更加丰富的交互方式呢&#xff1f;答案是肯定的&#…

Alibaba SpringCloud集成Nacos、Sentinel实现服务治理-17

关于服务治理 总体而言&#xff0c;限流和降级作为微服务架构中的重要机制&#xff0c;尽管在实现上可能有多种方式&#xff0c;但它们都着眼于保护服务提供者和消费者&#xff0c;在面对异常情况时确保系统稳定运行。限流关注于保护服务提供者&#xff0c;控制请求流量&#…

【linux系统学习教程 Day02】网络安全之Linux系统学习教程,管道,文件内容统计,过滤排序,去重,目录介绍

1-4 管道 管道符号&#xff1a; | &#xff0c;可以将前面指令的执行结果&#xff0c;作为后面指令的操作内容。 ## 比如过滤ip地址 ip addr | tail -4 | head -1 解释一下就是先执行 ip addr ,得到的结果当做 tail -4 的输入&#xff0c;意思就是查看ip addr 结果的后四行内容…

基于NIOS-II软核流水灯实现

文章目录 一、创建工程二、系统设计1. 在 “component library” 标签栏中找到 “Nios II Processor” 后点击 Add2. 在 ”Component Library” 标签栏中的查找窗口输入 jtag 找到 ”JTAG UART ”&#xff0c;然后点击 Add3. 添加片上存储器 On-Chip Memory(RAM)核4. 查找窗口输…

如何创建和运营新版Facebook粉丝专页

在众多平台中&#xff0c;Facebook粉丝专页无疑是连接全球消费者、扩展品牌影响力的重要工具。如果你是初次接触Facebook粉丝专页&#xff0c;可能会感到有些迷茫——毕竟&#xff0c;只是听说过它的好处&#xff0c;却不知道如何开始。 Facebook粉丝专页不仅是一个分享产品信…