单链表的实现(数据结构)

本篇博客主要是单链表(无头单项不循环)的实现的代码分享

说明:因为此单链表无头(哨兵位),可以说成没有初始化也可以说初始化时没有一个有效地址作为单链表的起始地址 例如下面代码中的plist == NULL。

  所以在后面函数(链表为空时,头插、尾插、插入)实现过程中需要将plist(单链表头结点地址)修改,就需要传址操作(在这里需要传单链表节点地址的地址),而且为了代码接口的一致性,在单链表函数实现中全部传了单链表节点地址的地址!

图解:

	SLNode* plist = NULL;//只是定义了一个单向链表节点的地址,而且地址还==NULLSLNodePushBack(&plist,1);

头文件Single List.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int SLNodeDataType;
typedef struct Single_Linked_ListNode
{SLNodeDataType data;struct Single_Linked_ListNode* next;
}SLNode;//
void SLNodePushBack(SLNode** pphead, SLNodeDataType x);
void SLNodePushFront(SLNode** pphead, SLNodeDataType x);void SLNodePopBack(SLNode** pphead);
void SLNodePopFront(SLNode** pphead);SLNode* SLNodeBuyNode(SLNodeDataType x);
void SLNodePrint(SLNode** pphead);SLNode* SLNodeFind(SLNode** pphead,SLNodeDataType x);void SLNodeInsert(SLNode** pphead, SLNode* pos, SLNodeDataType x);
void SLNodeErase(SLNode** pphead, SLNode* pos);void SLNodeInsertAfter(SLNode** pphead, SLNode* pos, SLNodeDataType x);
void SLNodeEraseAfter(SLNode** pphead, SLNode* pos);void SListDestroy(SLNode** pphead)

源文件Single Link.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Single List.h"SLNode* SLNodeBuyNode(SLNodeDataType x)
{SLNode* tmp = malloc(sizeof(SLNode));if (tmp == NULL){perror("malloc fail!");exit(1);}tmp->data = x;tmp->next = NULL;return tmp;
};
void SLNodePushBack(SLNode** pphead, SLNodeDataType x)
{assert(pphead);SLNode* pnewnode = SLNodeBuyNode(x);//链表为空,新节点做头节点if (*pphead == NULL){*pphead = pnewnode;return;}//链表不为空,找尾节点SLNode* ptail= *pphead;while (ptail->next != NULL){ptail = ptail->next;}ptail->next = pnewnode;};
void SLNodePushFront(SLNode** pphead, SLNodeDataType x)
{assert(pphead);SLNode* pnewnode = SLNodeBuyNode(x);//链表为空,新节点做头节点if (*pphead == NULL){*pphead = pnewnode;return;}//链表不为空pnewnode->next = *pphead;*pphead = pnewnode;}void SLNodePopBack(SLNode** pphead)
{assert(pphead);assert(*pphead);//确保有节点//只有一个节点if ((*pphead)->next == NULL){free(*pphead);//置空前不要忘了释放空间*pphead = NULL;return;//不需要再走了}//多节点,找尾节点前一个节点SLNode* ptailprev = *pphead;while ((ptailprev->next->next) != NULL){ptailprev = ptailprev->next;}free(ptailprev->next);ptailprev->next = NULL;}
void SLNodePopFront(SLNode** pphead)
{assert(pphead);assert(*pphead);//必须有节点一个节点//if ((*pphead)->next == NULL)//{//	free(*pphead);//	*pphead = NULL;//	return;//}多个节点SLNode* tmp = (*pphead)->next;free(*pphead);*pphead = tmp;}void SLNodePrint(SLNode** pphead)
{SLNode* pcur = *pphead;while (pcur){printf("%d->",pcur->data);pcur = pcur->next;}printf("NULL\n");
}SLNode* SLNodeFind(SLNode** pphead,SLNodeDataType x)
{assert(pphead);//遍历链表SLNode* pcur = *pphead;while (pcur){if (pcur->data == x){return pcur;}pcur=pcur->next;}//没找到return NULL;
}
void SLNodeInsert(SLNode** pphead, SLNode* pos, SLNodeDataType x)
{assert(pphead);assert(pos);//链表不为空assert(*pphead);SLNode* pnewnode = SLNodeBuyNode(x);//头节点插入if (pos == *pphead){SLNodePushFront(pphead,x);return;}//其他节点SLNode* prev = *pphead;while (prev->next!=pos){prev = prev->next;}prev->next = pnewnode;pnewnode->next = pos;
}
void SLNodeErase(SLNode** pphead, SLNode* pos)
{assert(pphead);assert(pos);assert(*pphead);if (*pphead == pos){  SLNodePopFront(pphead);return;}SLNode* prev= *pphead;while (prev->next != pos){prev = prev->next;}SLNode* pnext = pos->next;pos->next = NULL;free(pos);pos = NULL;prev -> next = pnext;
}void SLNodeInsertAfter(SLNode** pphead, SLNode* pos, SLNodeDataType x)
{assert(pphead);assert(pos);SLNode* pnewnode = SLNodeBuyNode(x);SLNode* pnext = pos->next;pos->next = pnewnode;pnewnode->next = pnext;}
void SLNodeEraseAfter(SLNode** pphead, SLNode* pos)
{assert(pphead);assert(pos);assert(pos->next);//pos pnext pnextnextSLNode* pnext = pos->next;SLNode* pnextnext = pnext->next;pos->next = pnextnext;pnext->next = NULL;free(pnext);pnext = NULL;}void SListDestroy(SLNode** pphead)
{assert(pphead);assert(*pphead);SLNode* pcur = *pphead;while (pcur){SLNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}

测试test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Single List.h"int main()
{SLNode* plist = NULL;SLNodePushBack(&plist,1);SLNodePushBack(&plist,2);SLNodePushBack(&plist,3);SLNodePushBack(&plist,4);SLNodePushBack(&plist,5);SLNodePrint(&plist);SLNodePushFront(&plist, 100);SLNodePushFront(&plist, 200);SLNodePushFront(&plist, 300);SLNodePushFront(&plist, 400);SLNodePrint(&plist);SLNodePopBack(&plist);SLNodePopBack(&plist);SLNodePrint(&plist);SLNodePopFront(&plist);SLNodePopFront(&plist);SLNodePopFront(&plist);SLNodePrint(&plist);SLNode* findinex = SLNodeFind(&plist,100 );if (findinex){printf("找到了\n");}else{printf("未找到\n");}SLNodeInsert(&plist,findinex,1000);SLNodePrint(&plist);SLNodeErase(&plist,findinex);SLNodePrint(&plist);SLNode* findinex2 = SLNodeFind(&plist, 1000);if (findinex2){printf("找到了\n");}else{printf("未找到\n");}//SLNodeErase(&plist, findinex2);SLNodePrint(&plist);SLNodeInsertAfter(&plist, findinex2, 666);SLNodePrint(&plist);SLNode* findinex3 = SLNodeFind(&plist,1000);if (findinex3){printf("找到了\n");}else{printf("未找到\n");}SLNodeEraseAfter(&plist, findinex3);SLNodePrint(&plist);return 0;SListDestroy(&plist);
}

这个博客如果对你有帮助,给博主一个免费的点赞就是最大的帮助

欢迎各位点赞,收藏和关注哦

如果有疑问或有不同见解,欢迎在评论区留言哦

后续我会一直分享双一流211西北大学本科生我自己的软件学习过程(C,数据结构,C++,Linux,MySQL)的学习干货以

及重要代码的分享

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

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

相关文章

倒计时!数境·第七届工业互联网数据创新应用大赛即将截止报名

共赴数据之旅&#xff0c;赋能工业未来&#xff01; 由深圳市宝安区人民政府和 中国信息通信研究院共同主办的 数境第七届工业互联网数据创新应用大赛 以“数实融合&#xff0c;助推新型工业化”为主题 聚焦先进制造、新能源和电子信息领域 设置算法赛和方案赛共三大赛道…

#QT(串口助手-界面)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a;编写串口助手 3.记录 接收框:Plain Text Edit 属性选择&#xff1a;Combo Box 发送框:Line Edit 广告&#xff1a;Group Box &#xff08;1&#xff09;仿照现有串口助手设计UI界面 &#xff08;2&#xff09;此时串口助手大…

爬虫入门到精通_框架篇15(Scrapy框架安装)

1 Scrapy安装 Scrapy的安装有多种方式&#xff0c;它支持Python2.7版本及以上或Python3.3版本及以上。下面说明Python3环境下的安装。 Scrapy依赖的库比较多&#xff0c;至少需要依赖库有Twisted14.0,lxml 3.4,pyOpenSSL 0.14。而在不同平台环境又各不相同&#xff0c;所以在安…

3/7—21. 合并两个有序链表

代码实现&#xff1a; 方法1&#xff1a;递归 ---->难点 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* mergeTwoLists(struct ListNode *list1, struct ListNode *list2) {/*1.如果l1为…

2024最新图标设计趋势!附超好用的图标工具清单

图标&#xff0c;在界面设计中的作用不容小觑。正所谓浓缩的就是精华&#xff0c;一个小小的图标&#xff0c;却有着高效传递信息、美化界面排版、提升用户体验的巨大能力。 既然图标如此重要&#xff0c;了解图标设计趋势对设计师来说几乎是必须要做的事&#xff0c;它可以让…

python3安装chrome,chromedriver亲测有效

客户用python写了个脚本&#xff0c;需要用到chrome和chromedriver扩展&#xff0c;结果说安装不了&#xff0c;各种报错&#xff0c;好吧我来研究一下。众所周知linux自带python2.7&#xff0c;根据报错查了一下资料发现是版本冲突导致的&#xff0c;系统自带2.7&#xff0c;代…

Python语言基础与应用-北京大学-陈斌-P32-31-计算和控制流-上机练习:创建并调用函数-字符集合的并集-上机代码

Python语言基础与应用-北京大学-陈斌-P32-31-计算和控制流-上机练习&#xff1a;创建并调用函数-字符集合的并集-上机代码 本文环境&#xff1a; win10 Thonny4.1.4 # 函数训练字符集合的并集 def my_union(str1,str2):list1 []list2 []i 0 while i < len(str1):lis…

springboot使用异步多线程

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 个人IP&#xff1a;shigen 在shigen之前的很多文章中&#xff0c;提到了线程池&#xff1a; 高性能API设计…

利用IP地址信息提升网络安全

在计算机网络中&#xff0c;IP地址是用于唯一标识网络设备的重要标识符。然而&#xff0c;由于网络中存在大量设备&#xff0c;有时会出现IP地址冲突的情况&#xff0c;即两个或多个设备在同一网络中使用了相同的IP地址&#xff0c;这可能导致网络连接故障和通信中断。本文将介…

蚂蚁SEO什么是蜘蛛池2024最新强势蜘蛛池

蜘蛛池是一种搜索引擎优化&#xff08;SEO&#xff09;策略&#xff0c;通过在互联网上建立大量的网站和链接&#xff0c;吸引搜索引擎的爬虫&#xff08;也称为“蜘蛛”&#xff09;访问&#xff0c;以提高网站的搜索排名和曝光率。以下是关于蜘蛛池的详细解释&#xff1a; 获…

FX110网:CTRL FX 是典型的诈骗平台!汇友发出肺腑之言

“CTRL FX 是一个典型的投资骗局&#xff0c;以‘出金缴税’等为幌子反复割韭菜&#xff0c;入金了这么多&#xff0c;但没有一次出金获得批准。揭露他们的骗局&#xff0c;保护受害者对我是一种宽慰。” 这是近日一汇友在对CTRL FX平台彻底失望后发出的声音。珍惜别的投资者用…

一个你可能不曾注意的小东西,Spring依赖注入Bean类型的8种情况

今天来讲的一个你可能不曾注意的小东西&#xff0c;那就是Spring依赖注入支持注入Bean的类型&#xff0c;这个小东西可能看似没有用但是实际又有点小用。 其实本来这周没打算写文章&#xff0c;但是突然之间就想到了之前有个妹子问过这个问题&#xff0c;并且网上这块东西说的…

学生课程参与度的一些情况

喊口号 日常校园中不乏各式各样的口号和标语。 但是能否落实到实处&#xff0c;非常难以评定的。 以学生为中心 实际上&#xff0c;学生对于课程几乎没有任何选择权和掌控权。 1&#xff0c;课程并非是学生自己选择的&#xff0c;还是培养方案安排的。 2&#xff0c;课程教…

nestjs 管道验证DTO

我将dto文件全收集到一个dto文件夹里&#xff0c;可按照文档建议。 1.安装依赖 pnpm i --save class-validator class-transformer参考文档https://github.com/typestack/class-transformerhttps://github.com/typestack/class-transformer https://github.com/typestack/cl…

使用测试驱动开发模式编写智能合约

hardhat简介 hardhat是一个以太坊智能合约开发框架&#xff0c;主要用于简化和加速以太坊区块链上的智能合约开、测试和部署&#xff0c;提供了许多工具帮助开发人员更轻松地构建和维护智能合约项目&#xff0c;以下是他的一些主要功能&#xff1a; 智能合约开发&#xff1a;h…

MySQL 针对逗号拼接的数据字段转行思路

一、MySQL 针对逗号拼接的数据字段转行思路 在 MySQL 中我们有可能为了方便操作&#xff0c;有时会将一个字段存储多个信息&#xff0c;使用英文逗号隔开&#xff0c;当然这种情况属于对数据库的设计上有些欠妥。但如果遇到了这种情况又需要对数据进行统计的情况就有点棘手了&…

STM32CubeIDE基础学习-设置输出HEX和BIN文件的方法

STM32CubeIDE基础学习-设置输出HEX和BIN文件的方法 前言 当某些时候&#xff0c;需要把一个程序下载到单片机里面进行功能验证或者看结果时&#xff0c;可以用串口软件来烧录程序&#xff0c;而不用再打开程序工程在线烧录程序这么麻烦了&#xff0c;那么就需要该工程文件夹下…

电脑记事本怎么查看字数 记事本字数便捷查看方法

在数字化的时代&#xff0c;电脑记事本已成为我记录生活、工作的得力助手。相较于传统的纸质笔记本&#xff0c;它的便捷性不言而喻&#xff1a;随时随地&#xff0c;打开就能写&#xff0c;无需担心纸张用尽或笔墨不干的尴尬。但有一个问题一直困扰着我&#xff0c;那就是如何…

UI学习 一

教程&#xff1a;Accessibility – Material Design 3 需要科学上网&#xff0c;否则图片显示不出来。设计教程没有图片说明&#xff0c;不容易理解。 优化UI方向 清晰可见的元素足够的对比度和尺寸重要性的明确等级一眼就能辨别的关键信息 传达某一事物的相对重要性 将重…

(二十二)从零开始搭建k8s集群——高可用kubernates集群搭建上篇

前言 本节内容分为上、中、下三篇&#xff0c;上篇主要是关于搭建k8s的基础环境&#xff0c;包括服务器基本环境的配置&#xff08;网络、端口、主机名、防火墙、交换分区、文件句柄数等&#xff09;、docker环境部署安装配置、镜像源配置等。中篇会介绍k8s的核心组件安装、k8…