c语言,单链表的实现----------有全代码!!!!

1.单链表的定义和结构

单链表是一种链式的数据结构,它用一组不连续的储存单元存反线性表中的数据元素。链表中的数据是以节点的形式来表示的,节点和节点之间相互连接

一般来说节点有两部分组成 1.数据域 :数据域用来存储各种类型的数据(浮点数,字符串,自定义类型的数据),2.指针域: 指针域用来存储的是指针,它用来指向下一个节点

 2.单链表的实现

SLlist.h

//定义单链表的节点
typedef int SLTDataType;
typedef struct SListNode
{SLTDataType Data;struct SListNode* next;//指向下一个节点的指针
}SLTNode;//增加新的节点
SLTNode* SLTBuyNode(SLTDataType x);//打印链表
void SLTPrint(SLTNode* phead);//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x);//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x);//尾删
void SLTPopBack(SLTNode** pphead);//头删
void SLTPopFront(SLTNode** pphead);//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x);//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos);//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x);//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos);//销毁链表
void SListDesTroy(SLTNode** pphead);

SLlist.c

//增加新的节点
SLTNode* SLTBuyNode(SLTDataType x) {//开辟一个节点大小的空间SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->Data = x;newnode->next = NULL;return newnode;
}//打印链表
void SLTPrint(SLTNode* phead) {//循环打印,当phead指向NULL(也就是尾节点指向的下一个节点)时停止while (phead){printf("%d->", phead->Data);//让phead指向下一个节点,并赋值给pheadphead = phead->next;}printf("NULL\n");
}//尾插
//想要修改值就要传地址,不能传值。而phead是个指针,我们要拿二级指针接收
void SLTPushBack(SLTNode** pphead, SLTDataType x) {assert(pphead);//*pphead说明第一个节点为NULL也就是说链表为空if (*pphead == NULL) {*pphead = SLTBuyNode(x);    //直接创建一个新的节点}//链表不为NULL时尾插else{SLTNode* ptail = *pphead;    //创建一个节点,从头开始遍历找尾节点//遍历链表,找到尾节点while (ptail->next)    //下一个节点为NULL表达式为假,就说明已经找到了尾节点{ptail = ptail->next;}ptail->next = SLTBuyNode(x);   //找到为节点,让尾节点指向新的节点,完成尾插}}//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x) {assert(pphead);SLTNode* newnode = SLTBuyNode(x);    //创建一个新的节点准备进行头插newnode->next = *pphead;      //直接让新节点指向原先的第一个节点*pphead = newnode;            //让新的节点成为新的第一个节点//在是有一个节点的情况下也可以完美完成任务
}//尾删
//可能要修改第一个节点,所以得传地址,用二级指针** pphead接收
void SLTPopBack(SLTNode** pphead) {//列表不能为NULL不然删啥assert(pphead && *pphead);SLTNode* ptail;    //找尾节点SLTNode* prev;    //尾节点前一个节点,它将来可能是新的尾节点prev = ptail = *pphead;//只有一个节点,直接删除不用找尾节点前面的节点if (ptail->next == NULL){//改变头节点需要用到pphead,对它进行解引用得到原第一个节点free(*pphead);*pphead = NULL;}//有一个以上的节点,开始找尾节点,进行尾删else{//当 某个节点的下一个节点(指向)->NULL 时找到尾节点while (ptail->next){prev = ptail;ptail = ptail->next;}free(ptail);    //找到了原尾节点直接释放ptail = NULL;   prev->next = NULL;    //让新的位节点(指向)->NULL}
}//头删
//肯定会修改到第一个节点,要传地址,拿二级指针** pphead接收
void SLTPopFront(SLTNode** pphead) {assert(pphead && *pphead);SLTNode* ptail = *pphead; //记录原第一个节点//改变原第一个节点*pphead = ptail->next;   //让第二个节点成为,新的第一个节点//直接释放原第一个节点free(ptail);ptail = NULL;
}//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x) {//空链表的话不用找了assert(phead);SLTNode* pcur = phead;//让pcur遍历链表,直到尾节点指向的下一个节点NULL,说明没有这个元素while (pcur){if(pcur->Data == x){return pcur;    //有这个元素,直接返回这个元素所在节点的地址}pcur = pcur->next;}return NULL;
}//在指定位置之前插入数据
//可能会改变第一个节点要传地址,拿二级指针** pphead接收
//pos 为指定位置
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x) {assert(pphead);//创新的节点SLTNode* newnode = SLTBuyNode(x);SLTNode* prev = *pphead; //prev用找到pos之前的位置//如果只有一个节点,会出现prev找不到pos的情况,因为一开始这两的位置一样,prev的下一个位置永远不可能是posif (pos == prev) {SLTPushFront(pphead, x);}//有多个节点的情况,开始找pos节点并再此之前插入else {//找pos之前的节点prevwhile (prev->next != pos){prev = prev->next;}//拿1 -> 2 -> NULL 我们要在1(prev) 2(pos)之间插入3演示newnode->next = pos;     //先让新的节点,指向pos   3 -> 2 ->NULLprev->next = newnode;    //在让prev节点指向新的节点  1 -> 3 -> 2 ->NULL}    
}//在指定位置之后插入数据
//不存在改变第一个节点的情况,传第一个节点值过来就够用
void SLTInsertAfter(SLTNode* pos, SLTDataType x) {//指定的位置不能为NULL,要不然谁知道你想要在谁之后插入数据assert(pos);创建新的节点SLTNode* newnode = SLTBuyNode(x);SLTNode* del = pos->next;  //del为pos之后的节点//如果只有一个节点,那么pos指向的下一个节点为NULL,这套逻辑依旧适用//拿1 -> 2 -> 3 -> NULL 我们要再2(pos)3(del)之间插入4newnode->next = del;  //先让新的节点指向del   4 ->3 -> NULLpos->next = newnode;  //在让pos指向新的节点   1 -> 2 -> 4 -> 3 -> NULL}//删除pos节点
//如果删除的是第一点,得传地址,因为第一个节点会发生变化
void SLTErase(SLTNode** pphead, SLTNode* pos) {//链表不能为NULL不然删啥assert(pphead && pos && *pphead);SLTNode* del = pos->next;   //del为pos之后的节点SLTNode* prev = *pphead;    //prev为pos之前的节点//如果只有一个节点,直接删即可,不用去找pos前一个节点,这样找找不到if (pos == del)//pos = del 我搞错了,这样就赋值了{//头删,传头结点的地址也就是ppheadSLTPopFront(pphead);}//不止一个节点,找pos之前的节点prevelse{while (prev->next != pos){prev = prev->next;}//把pos前一个节点prev和后一个节点del连接起来,在把pos节点释放prev->next = del;free(pos);pos = NULL;}
}//删除pos之后的节点
//第一个节点不可能被修改,因为即使只有一个节点,第一个节点后面的节点也是NULL
void SLTEraseAfter(SLTNode* pos) {//pos后面的节点不能为NULL不然删啥assert(pos && pos->next);SLTNode* del = pos->next;    //del为pos之后的节点//1->2->3,让1跟3连接起来,在释放2pos->next = del->next;free(del);del = NULL;
}//销毁链表
//涉及修改第一个,需要接收头结点地址
void SListDesTroy(SLTNode** pphead) {assert(pphead && *pphead);SLTNode* pcur = *pphead;     //pcur用来遍历链表,依次销毁SLTNode* next;     //next为当前需销毁节点的下一个节点,不然直接销毁就找不到下一个节点了//如果pcur为NULL,说明走到了尾节点指向的NULL,链表销毁完毕while (pcur){next = pcur->next;	//先保存当前需要销毁节点的下一个节点的地址free(pcur);         //销毁当前节点pcur = next;        //走向下一个节点}*pphead = NULL;    //让第一个节点为NULL,链表销毁完毕后为NULL
}

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

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

相关文章

Windows系统下查看C语言文件反汇编

一、配置编译器环境变量 1.下载mingw64 MinGW 的全称是:Minimalist GNU on Windows ,MinGW 就是 GCC 的 Windows 版本 。 MinGW-w64 与 MinGW 的区别在于 MinGW 只能编译生成32位可执行程序,而 MinGW-w64 则可以编译生成 64位 或 32位 可执行…

day11 | 栈与队列 part-3 (Go) | 239 滑动窗口最大值、347 前 K 个高频元素 (好难)

今日任务 239 滑动窗口最大值 (题目:. - 力扣(LeetCode) )347 前 K 个高频元素 (题目: . - 力扣(LeetCode) )栈与队列总结 239 滑动窗口最大值 题目:. - 力扣(LeetCode) 给你一个整数数组 nums&#xf…

处理json文件,并将数据汇总至Excel表格

从scores.jason文件中读取学生信息,输出学生的学号,姓名,各科成绩,平均分, 各科标准差 scores.jason {"学院": "计算机学院","班级": "2022级1班","成绩": [{"学号": 1001,&q…

使用avx2 指令集加速向量算法运算

使用cpu-z 查看cpu指令集 2 向量加&#xff0c;乘法&#xff0c;除法 我们使用向量加&#xff0c;为什么函数是0 到 8 的计算&#xff0c;因为avx2 寄存器为256位&#xff0c;同时设置启动增强指令集 #include <immintrin.h> // 引入包含AVX2指令集的头文件void vecto…

C++类和对象:赋值重载,const成员

文章目录 1.赋值运算符重载1.1运算符重载1.2 赋值运算符重载1.3 前置和后置重载 2.日期类的实现3. const成员函数4 取地址及const取地址操作符重载 上文介绍了前三个默认成员函数&#xff0c;本文会介绍剩下三个&#xff0c; 赋值重载会重点展开。 1.赋值运算符重载 1.1运算符…

代码随想录 Day17 字符串 | LC344 反转字符串 LC541 反转字符串II 卡码网54替换数字

一、反转字符串 题目&#xff1a; 力扣344&#xff1a;反转字符串 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题…

微服务相关

1. 微服务主要七个模块 中央管理平台&#xff1a;生产者、消费者注册&#xff0c;服务发现&#xff0c;服务治理&#xff0c;调用关系生产者消费者权限管理流量管理自定义传输协议序列化反序列化 2. 中央管理平台 生产者A在中央管理平台注册后&#xff0c;中央管理平台会给他…

不说成为Linux高级工程师,但成为合格的软件开发人员还是够了,一文深入浅出的精炼总结Linux核心知识点,掌握Linux的使用与高阶技巧

不说成为Linux高级工程师&#xff0c;但成为合格的软件开发人员还是够了&#xff0c;一文深入浅出的精炼总结Linux核心知识点&#xff0c;掌握Linux的使用与高阶技巧。 Linux 的学习对于一个程序员的重要性是不言而喻的。前端开发相比后端开发&#xff0c;接触 Linux 机会相对…

图像基础—图像分类

图像通常分为二值图像、灰度图像和彩色图像 图 1-3 二值图像、灰度图像和彩色图像 &#xff08;1&#xff09;二值图像 二值图像又称为黑白图像&#xff0c;图像中任何一个点非黑即白&#xff0c;要么为白色&#xff08;像素 为 255&#xff09;&#xff0c;要么为黑色&#x…

20240417,友元 FRIEND

本来要学习的吃瓜吃了一下午 目录 3.1 全局函数做友元 3.2 友元类 3.3 成员函数做友元 三&#xff0c;友元 3.1 全局函数做友元 #include<iostream> using namespace std; class Building {friend void goodGay(Building* building);//好朋友&#xff0c;可以访问…

YooAsset快速入门

文章目录 YooAsset快速入门指南&#xff1a;YooAsset学习核心要掌握的要点主要包括以下几个方面&#xff1a;基于YooAsset进行游戏资源管理的应用实例 YooAsset快速入门指南&#xff1a; YooAsset是一款专为游戏开发设计的资产管理和分发系统&#xff0c;它能够帮助开发者高效…

2024阿里云4核8G服务器租用优惠价格700元一年

阿里云4核8G服务器租用优惠价格700元1年&#xff0c;配置为ECS通用算力型u1实例&#xff08;ecs.u1-c1m2.xlarge&#xff09;4核8G配置、1M到3M带宽可选、ESSD Entry系统盘20G到40G可选&#xff0c;CPU采用Intel(R) Xeon(R) Platinum处理器&#xff0c;阿里云优惠 aliyunfuwuqi…

怎样将excel的科学计数法设置为指数形式?

对了&#xff0c;这个问题中所谓的“指数形式”是指数学上书写的右上标的指数格式&#xff0c;能不能通过单元格设置来做这个格式的转换呢&#xff1f; 一、几个尝试 以下&#xff0c;以数字123000为例来说明。 情况1.转换成数学上的书写方式&#xff0c;如下图的样子&#x…

Easy GIS .NET GMap.Net

Easy GIS .NET & GMap.Net .NET 环境下非常简单的GIS地图开发库。 Easy GIS .NET 一个简单的GIS 桌面应用程序&#xff0c;实现了地图瓦片加载、shapefile文件和csv文件加载渲染、地图坐标系统设置及转换等等基本功能&#xff0c;非常简单易用。 Easy GIS .NET is an o…

算法之归并排序(java、python、c++)

一、JAVA 摘录归并详细分析 ✈✈✈✈✈ package algorithm.归并;import java.util.Arrays;public class Fenzhi {public static void main(String[] args) {int [] arr {8,4,1,2,7,6,3,5};mergeSort(arr, 0, arr.length-1, new int[8]);System.out.println(Arrays.toString(a…

【Godot4自学手册】第三十七节钥匙控制开门

有些日子没有更新了&#xff0c;实在是琐事缠身啊&#xff0c;今天继续开始自学Godot4&#xff0c;继续完善地宫相关功能&#xff0c;在地宫中安装第二道门&#xff0c;只有主人公拿到钥匙才能开启这扇门&#xff0c;所以我们在合适位置放置一个宝箱&#xff0c;主人公开启宝箱…

Tcpdump -r 解析pcap文件

当我们使用命令抓包后&#xff0c;想在命令行直接读取筛选怎么办&#xff1f;-r参数就支持了这个 当你使用 tcpdump 的 -r 选项读取一个之前捕获的数据包文件&#xff0c;并想要筛选指定 IP 地址和端口的包时&#xff0c;你可以在命令中直接加入过滤表达式。这些过滤表达式可以…

2024 年 Web 前端开发趋势

希腊哲学家赫拉克利特认为&#xff0c;变化是生命中唯一不变的东西。这句话适用于我们的个人生活、行业和职业领域。 尤其是前端开发领域&#xff0c;新技术、开发趋势、库和框架不断涌现&#xff0c;变化并不陌生。最近发生的一些事件正在改变开发人员构建网站和 Web 应用的方…

git 分支-变基

在git中&#xff0c;将一个分支的更改集成到另一个分支有两种主要方式&#xff1a;合并&#xff08;merge&#xff09;和变基&#xff08;rebase&#xff09;。在本节中&#xff0c;将学习什么是变基&#xff0c;如何执行变基操作&#xff0c;为什么它是一个非常强大的工具&…

【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题9

【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题9 信息安全管理与评估 网络系统管理 网络搭建与应用 云计算 软件测试 移动应用开发 任务书&#xff0c;赛题&#xff0c;解析等资料&#xff0c;知识点培训服务 添加博主wx&#xff1a;liuliu548…