【C语言零基础入门篇 - 15】:单链表
文章目录
- 单链表
- 链表的基本概念
- 单链表功能的实现
- 单链表的初始化
- 单链表新结点的创建
- 单链表头插法
- 单链表的输出
- 单链表的查找
- 单链表修改
- 单链表的删除
- 单链表所有数据结点释放
- 源代码
单链表
链表的基本概念
一、什么是链表?
链表是数据结构中线性表的一种,其中的每个元素实际上是一个单独的结构体对象,而所有对象都通过每个元素中的指针链接在一起。
什么是结点:链表中每个结构体对象叫做结点。
什么是首元结点:其中第一个数据结点。
什么是头结点:如果第一个结点不用于存储数据,只用于代表链表的起始点,则这个结点称为链表的头结点。

二、单链表的特点
1、单链表没有固定的长度,可以自由增加节点。
2、单链表能够实现快速的插入删除数据。
3、与数组类似,单链表也是一种线性数据结构。
4、单链表的尾结点的后继必定指向空。
单链表和数组的区别:数组是顺序存储的,而单链表是链式存储的。
链表的结构示意图:

单链表功能的实现
链表的基本操作:增、删、改、查。
单链表节点的插入和删除结构示意图:

单链表的初始化



单链表新结点的创建

单链表头插法


单链表的输出



单链表的查找



单链表修改


单链表的删除


- 单链表删除结点的补充:

单链表所有数据结点释放


源代码
#include<stdio.h>
#include<stdlib.h>
#define TYPE int //数据类型通过定义宏的形式来进行灵活运用
#define PRINT(a) printf("%d-->", a)
#define PRINTINDEX(b, c) printf("元素值是%d\t 位置是%d\n\n", b,c)
//结点的类型 声明结点的类型
struct NODE
{int data; //数据域struct NODE*next; //指针域保存下一个结点的地址 struct NODE*//next是一个成员
};//头结点类型 链表结构
struct List
{int len; //保存单链表中的结点个数(不包括头结点)struct NODE*front; //头指针 指向首元结点struct NODE*back; //尾指针 指向尾结点
};//创建单链表结构 从堆区来申请内存 把首地址返回给list
struct List*initList()
{//申请单链表结构内存struct List*temp = (struct List*)malloc(sizeof(struct List));//初始化单链表结构的成员temp->len = 0;temp->front = NULL;temp->back = NULL;return temp;
}//单链表结点的创建
struct NODE*CreateNode(TYPE data)
{struct NODE*temp = (struct NODE*)malloc(sizeof(struct NODE));temp->data = data; //把数据放进新结点temp->next = NULL; //防止野指针的出现return temp;
}//单链表结点的插入 头插法
void insertHead(struct List*head, TYPE data) //list表示要增加数据的单链表
{//1、作为第一个数据结点插入单链表中 头指针与尾指针都需要改变指向if (head->front == NULL) //或者head->len == 0{//1、要生成一个新的结点//2、让头指针和尾指针都指向这个新结点head->front = head->back = CreateNode(data);head->len++;//单链表结点的数量+1}else//不是第一个数据结点 只需改变头指针的指向{//生成一个新的结点struct NODE*S = CreateNode(data);//新结点S指针域保存原来的首元结点的地址S->next = head->front;//更新头指针,指向新结点Shead->front = S;head->len++; //单链表结点的数量+1}
}//输出单链表中所有的数据
void print(struct List*head)
{struct NODE*p = head->front;while (p != NULL){PRINT(p->data); //输出p指向的结点里面的数据p = p->next; //p指向下一个结点//p++;不能使用,单链表的物理内存不连续}printf("\n\n");
}//单链表元素的查找 根据指定值来查找元素,并且输出元素的位置
void find(struct List*head, int val) //head=list val表示要查找的数据
{struct NODE*p = head->front;//p指向首元结点int index = 0; //index表示指定元素的位置while (p != NULL){index++;if (p->data == val){PRINTINDEX(p->data, index);//输出元素值和位置}p = p->next; //p指向下一个结点}
}//单链表元素的修改 根据指定值
void modify(struct List*head, TYPE val, TYPE data)
//val要被修改的数据 data要修改成的数据
{struct NODE*p = head->front; //p指向首元结点while (p != NULL){if (p->data == val){p->data = data;//修改数据}p = p->next; //p指向下一个结点}
}//单链表的删除 根据指定值来删除数据
void delete(struct List*head, TYPE val) //head=list val表示要被删除的数据
{//1、要找到要被删除的数据struct NODE*p1 = head->front; //p指向首元结点struct NODE*p2 = NULL;while (p1 != NULL){if (p1->data == val) //找到了要被删除的数据{//情况一:p1指向是首元结点,需要更新头指针的指向if (p1 == head->front){head->front = p1->next; //让p1的直接后继结点成为新的首元结点free(p1);p1 = head->front; //让p1指向新的首元结点}//情况二:p1指向的是尾结点,需要更新尾指针else if (p1 == head->back){p2->next = p1->next; //给尾指针的结点域置空head->back = p2;free(p1);p1 = NULL;}//情况三:p1指向的结点是中间结点else{//p2的指针域指向p1的后继结点p2->next = p1->next;//释放删除结点free(p1);//更新p1p1 = p2->next;}}else //p2指向p1的前驱节点{p2 = p1;p1 = p1->next;}}
}//假设头结点也是struct node
void delete2(struct NODE*head, TYPE val) //val表示要被删除的数据
{struct NODE*p1 = head;struct NODE*p2 = head->next;while (p2 != NULL){if (p2->data = val){p1->next = p2->next;free(p2);p2->next = p1->next;}else{p1 = p1->next;p2 = p2->next;}}
}//整个单链表结点的释放 释放所有的数据结点 不是释放头节点
void AllClear(struct List*head)
{struct NODE*p = head->front; //p指向首元结点while (p != NULL){head->front = p->next;free(p);p = head->front;}head->front = head->back = NULL;//防止野指针出现
}int main()
{struct List *list = NULL; //list指向单链表 通过list来管理这个单链表list = initList(); //调用创建单链表函数//插入5个数据for (int j = 1; j <= 5; j++){insertHead(list, j);}print(list);//find(list, 4);//modify(list, 5, 9);//print(list);delete(list, 4);print(list);AllClear(list);print(list);return 0;
}
相关文章:
【C语言零基础入门篇 - 15】:单链表
文章目录 单链表链表的基本概念单链表功能的实现单链表的初始化单链表新结点的创建单链表头插法单链表的输出单链表的查找单链表修改单链表的删除单链表所有数据结点释放源代码 单链表 链表的基本概念 一、什么是链表? 链表是数据结构中线性表的一种,其…...
Linux主流Web服务器:你选择哪一款?
在Linux环境下,选择Web服务器通常取决于特定需求、资源限制、以及对性能的期望。以下是对几款主流Linux Web服务器的详细分析: 1. Apache HTTP Server - 特点:Apache是功能最全面的Web服务器之一,支持模块化架构,拥…...
光耦知识分享:解读晶体管光耦主要性能指标
晶体管光耦是一种常用的光电耦合器,用于隔离和传输电信号,它包含有光电发射管和接收晶体管两个主要部分。解读晶体管光耦的主要指标有助于了解其性能和应用范围,主要指标包括: 最大工作电压(V_R_MAX)&…...
laravel public 目录获取
在Laravel框架中,public目录是用来存放公共资源的,如CSS、JS、图片等。你可以通过多种方式获取public目录的路径。 方法一:使用helper函数public_path() $path public_path(); 方法二:使用Request类 $path Request::root().…...
强化学习策略买卖股票的效果如何?
Github 项目: GitHub - daocodedao/stable-baselines-stock: 深度强化学习自动炒股 主体参考了 https://github.com/wangshub/RL-Stock,修改了一些 requirements 修改到新版本支持 macstable-baselines 改为 stable-baselines3 使用强化学习预测股价…...
Kotlin 基本介绍(一)
导读大纲 1.1.1 Kotlin 是安全的1.1.2 Kotlin 具有互操作性1.1.3 什么是 idiomatic Kotlin? 1.1.1 Kotlin 是安全的 一般来说,当我们说一种编程语言是安全的 我们指的是它的设计可以防止程序中出现某些类型的错误当然,这并不是绝对的;没有一种语言能防止所有可能出现…...
Cocos Creator发布Moloco平台试玩广告(PlayableAd)
官方文档 主要遇到了两点问题。 1.HTML文件内的body需要注入 <script>window.FBPlayableOnCTAClick () > {(typeof FbPlayableAd undefined) ? alert(FBPlayableAd.onCTAClick) : FbPlayableAd.onCTAClick()}</script> 2.跳转商店使用 window.parent.postM…...
七种修复错误:由于找不到msvcr110.dll 无法继续执行的方法
当你在运行某些程序时遇到“找不到msvcr110.dll”的错误提示,这通常意味着你的系统缺少了Microsoft Visual C 2012 Redistributable包中的一个重要文件。这个DLL文件是Microsoft Visual C Redistributable的一部分,用于支持许多使用Visual C编写的软件和…...
Python模拟鼠标轨迹[Python]
一.鼠标轨迹模拟简介 传统的鼠标轨迹模拟依赖于简单的数学模型,如直线或曲线路径。然而,这种方法难以捕捉到人类操作的复杂性和多样性。AI大模型的出现,能够通过深度学习技术,学习并模拟更自然的鼠标移动行为。 二.鼠标轨迹算法实…...
Ubuntu搭建java开发环境
一:Ubuntu安装 1、下载Ubuntu 24.04.1 LTS 官网下载地址:https://releases.ubuntu.com/24.04.1/ubuntu-24.04.1-desktop-amd64.iso 可以直接点击这里下载 2、使用VMware安装 新建虚拟机 之后一直下一步,到如下界面,选择 刚刚…...
新能源汽车知识点集萃
功能安全-->ISO26262/GB∕T 34590 2021 信息安全--->ISO21434 预期功能安全--->ISO21448 建模规范-->MAAB/JMAAB/MISAR C Codeing Standard; 开发流程--CMMI/IATF16949//ASPICE(Automotive SPICE)/产品规划/概念开发/设计开发/试制试验与…...
c++234继承
#include<iostream> using namespace std;//public 修饰的成员便俩个和方法都能使用 //protected:类的内部 在继承的子类中可使用 class Parents { public:int a;//名字 protected:int b;//密码 private:int c;//情人public:void printT(){cout << &quo…...
Axios 封装网络请求
1 简介 通过Axios的请求拦截器和响应拦截器实现登录拦截,参数封装。 注意:前提是你的vue已经安装了Axios。 附安装代码: npm install axios 2 封装代码 2.1 utils文件夹下创建 request.js // 网络请求方法 import axios from axios impor…...
LeetCode 面试经典150题 190.颠倒二进制位
复习知识:正数的原码、反码、补码相同,负数的反码在其原码的基础上, 符号位不变,其余各个位取反,负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后1 (即在反码的基础上1)。 题目:颠倒给定的 32 位无符号…...
vulhub搭建漏洞环境docker-compose up -d命令执行报错以及解决方法汇总
在利用vulhub靶场搭建环境进行漏洞复现时,我们通常要使用这一步命令: docker-compose up -d 但是经常报错,今天我们来说几个常见的报错以及解决方法: 1.报错提示: ERROR: Couldnt connect to Docker daemon at httpdoc…...
C++ 简介
目录 面向对象程序设计 标准库 ANSI 标准 学习 C C 的使用 标准化 C 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言,支持过程化编程、面向对象编程和泛型编程。 C 被认为是一种中级语言,它综合了高级语言和低级语言的特点…...
shardingjdbc分库分表原理
一 Mysql的瓶颈 二 解决方案 三 hash环算法 四 雪花算法...
C++泛型编程:模版
引言 泛型编程(Generic Programming)是一种编程范式,允许编写与类型无关的代码,从而使程序更加灵活和可重用。在C中,泛型编程主要通过模板(Templates)来实现。模板使得我们可以编写通用…...
一道涉及 Go 中的并发安全和数据竞态(Race Condition)控制的难题
这是一道涉及 Go 中的并发安全和数据竞态(Race Condition)控制的难题。 问题描述: 你需要实现一个并发安全的计数器 SafeCounter,该计数器允许多个 Goroutine 同时对其进行读写操作。计数器会存储每个键的计数值。 具体要求&am…...
如何降低H5商城系统的开发成本
前言 H5商城系统通过多种策略来降低开发成本。以下是对这些策略的详细介绍: 一、选择合适的开发平台 原生开发与跨平台开发:原生开发使用HTML5、CSS3和JavaScript等Web技术,虽然性能更佳、用户体验更好,但开发成本相对较高。而…...
Node.js 流处理:高效处理大数据的艺术
Node.js 流处理:高效处理大数据的艺术 什么是流? 在 Node.js 中,流(Stream)是处理大量数据的抽象接口。它允许我们逐块读取或写入数据,而不需要一次性将全部数据加载到内存中。 为什么需要流? 想…...
Perplexity词组搭配查询深度解析(工业级语料验证版):基于127万条真实英文语境的搭配强度阈值模型首次公开
更多请点击: https://codechina.net 第一章:Perplexity词组搭配查询深度解析(工业级语料验证版):基于127万条真实英文语境的搭配强度阈值模型首次公开 Perplexity 不仅是语言模型评估的核心指标,更可转化为…...
Linux 软件包管理(含上机实例)
文章目录软件包管理一、知识要点1.rpm作用2.安装问题1:文件已被安装问题2:文件冲突问题3:未解决依赖关系3.卸载rpm包4.升级rpm包5.查询已安装的软件包的数据库6.验证软件包完整性二、YUM的使用yum简述yum命令集三、上机任务6 软件包管理 一、…...
用STM32F103C8T6给小车装上‘眼睛’:HC-SR04超声波+SG90舵机云台避障保姆级教程
用STM32F103C8T6打造智能小车感知系统:超声波与舵机云台的深度整合实战 在嵌入式系统开发领域,赋予机器"感知-决策-执行"的能力是一个令人着迷的课题。当我们把目光投向智能小车这个经典平台时,如何让它像生物一样具备环境感知能力…...
Augmentoolkit事实数据生成管道:打造精准问答AI的终极方法
Augmentoolkit事实数据生成管道:打造精准问答AI的终极方法 【免费下载链接】augmentoolkit Create Custom LLMs 项目地址: https://gitcode.com/gh_mirrors/au/augmentoolkit 想要创建专属的领域专家AI吗?Augmentoolkit事实数据生成管道为您提供了…...
告别串口助手!用手机APP和ESP-01S模块,5分钟搞定51单片机无线控制LED
手机APP直连ESP-01S:零门槛实现51单片机LED无线控制 在物联网原型开发中,摆脱串口助手的束缚,直接用手机APP控制硬件设备,是许多初学者的迫切需求。本文将带你用最常见的ESP-01S模块和任意一款TCP调试APP,在5分钟内搭建…...
RISC-V RTOS任务栈与上下文切换:寄存器保存策略与栈初始化详解
1. 项目概述与核心问题上一篇文章我们聊了RISC-V内核单片机移植RTOS时,任务切换的“开关”——中断与异常机制是如何工作的。今天,我们顺着这个思路,深入到最核心的“现场保护”环节:当一个任务被切换出去时,它的“工作…...
iPaaS厂商:五家主流集成平台的技术与市场观察
在数字化转型的深水区,企业级集成平台即服务(iPaaS)正在成为IT架构的“神经系统”。国内外众多厂商纷纷布局,形成了从全域智能集成到轻量SaaS连接的多极化格局。本文基于公开资料,对五家具有代表性的iPaaS厂商及其核心…...
写给前端的 CANN-ops-transformer:昇腾Transformer进阶算子库到底是啥?
写给前端的 CANN-ops-transformer:昇腾Transformer进阶算子库到底是啥? 之前有兄弟跑大模型,问我:“哥,我想 用 FlashAttention,但 ATB 太重了,有没有轻量点的库?” 好问题。今天来说…...
革命性AI背景移除:obs-backgroundremoval实现零绿幕专业级虚拟背景
革命性AI背景移除:obs-backgroundremoval实现零绿幕专业级虚拟背景 【免费下载链接】obs-backgroundremoval An OBS plugin for removing background in portrait images (video), making it easy to replace the background when recording or streaming. 项目地…...
