重生之“我打数据结构,真的假的?”--2.单链表(无习题)
C语言中的单链表总结
单链表是一种基础的数据结构,广泛应用于C语言编程中。它由节点组成,每个节点包含数据和指向下一个节点的指针。单链表的优点在于动态内存分配和高效的插入与删除操作。本文将详细探讨单链表的定义、基本操作、应用场景以及相关示例代码。
一、单链表的基本结构
单链表由多个节点组成,每个节点包含两部分:
- 数据部分:存储实际数据。
- 指针部分:指向下一个节点的指针。
节点的定义
在C语言中,我们可以使用结构体来定义单链表的节点。
typedef struct Node {int data; // 数据部分struct Node* next; // 指向下一个节点的指针
} Node;
二、单链表的基本操作
1. 创建单链表
创建单链表通常需要一个头指针,用于指向链表的第一个节点。若链表为空,头指针为NULL。
Node* createList() {return NULL; // 返回空链表
}
2. 插入节点
2.1 在头部插入
在链表的头部插入新节点是最简单的操作。我们需要创建一个新节点,并将其指向当前的头节点。
Node* insertAtHead(Node* head, int newData) {Node* newNode = (Node*)malloc(sizeof(Node)); // 动态分配内存newNode->data = newData; // 设置新节点的数据newNode->next = head; // 新节点指向原头节点return newNode; // 返回新的头节点
}
2.2 在尾部插入
在尾部插入节点需要遍历链表找到最后一个节点,然后将其指针指向新节点。
Node* insertAtTail(Node* head, int newData) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = newData;newNode->next = NULL; // 新节点的下一个指针为NULLif (head == NULL) {return newNode; // 如果链表为空,返回新节点}Node* temp = head;while (temp->next != NULL) {temp = temp->next; // 遍历到最后一个节点}temp->next = newNode; // 将最后一个节点的next指针指向新节点return head;
}
3. 删除节点
删除节点通常需要指定要删除的节点值,遍历链表找到该节点并进行删除。
Node* deleteNode(Node* head, int key) {Node* temp = head;Node* prev = NULL;// 如果头节点包含要删除的值if (temp != NULL && temp->data == key) {head = temp->next; // 更新头节点free(temp); // 释放内存return head;}// 遍历链表查找要删除的节点while (temp != NULL && temp->data != key) {prev = temp;temp = temp->next;}// 如果未找到要删除的节点if (temp == NULL) {return head;}// 解除节点的链接并释放内存prev->next = temp->next;free(temp);return head;
}
4. 查找节点
查找节点根据值查找节点的位置。
Node* search(Node* head, int key) {Node* current = head;while (current != NULL) {if (current->data == key) {return current; // 返回找到的节点}current = current->next; // 继续遍历}return NULL; // 未找到
}
5. 遍历链表
遍历链表通常用于显示链表中的所有数据。
void traverseList(Node* head) {Node* temp = head;while (temp != NULL) {printf("%d -> ", temp->data);temp = temp->next;}printf("NULL\n"); // 显示链表结束
}
6. 反转链表
反转链表操作是将链表的指向反转,使最后一个节点变为第一个节点。
Node* reverseList(Node* head) {Node* prev = NULL;Node* current = head;Node* next = NULL;while (current != NULL) {next = current->next; // 保存下一个节点current->next = prev; // 反转指针prev = current; // 移动prev和currentcurrent = next;}return prev; // 返回新的头节点
}
三、单链表的应用
单链表在许多场景中都有应用,包括:
- 动态数据存储:当数据量不固定时,链表能有效利用内存。
- 实现栈和队列:单链表可以轻松实现栈和队列的操作。
- 缓存管理:可以用于实现LRU缓存。
- 图的邻接表表示:链表可以表示图中节点之间的连接关系。
四、完整示例
下面是一个完整的单链表示例,演示了所有基本操作。
#include <stdio.h>
#include <stdlib.h>typedef struct Node {int data;struct Node* next;
} Node;Node* createList() {return NULL;
}Node* insertAtHead(Node* head, int newData) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = newData;newNode->next = head;return newNode;
}Node* insertAtTail(Node* head, int newData) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = newData;newNode->next = NULL;if (head == NULL) {return newNode;}Node* temp = head;while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;return head;
}Node* deleteNode(Node* head, int key) {Node* temp = head;Node* prev = NULL;if (temp != NULL && temp->data == key) {head = temp->next;free(temp);return head;}while (temp != NULL && temp->data != key) {prev = temp;temp = temp->next;}if (temp == NULL) {return head;}prev->next = temp->next;free(temp);return head;
}Node* search(Node* head, int key) {Node* current = head;while (current != NULL) {if (current->data == key) {return current;}current = current->next;}return NULL;
}void traverseList(Node* head) {Node* temp = head;while (temp != NULL) {printf("%d -> ", temp->data);temp = temp->next;}printf("NULL\n");
}Node* reverseList(Node* head) {Node* prev = NULL;Node* current = head;Node* next = NULL;while (current != NULL) {next = current->next;current->next = prev;prev = current;current = next;}return prev;
}int main() {Node* head = createList();head = insertAtHead(head, 1);head = insertAtTail(head, 2);head = insertAtTail(head, 3);head = insertAtHead(head, 0);printf("Current List: ");traverseList(head);head = deleteNode(head, 2);printf("After Deleting 2: ");traverseList(head);Node* foundNode = search(head, 1);if (foundNode) {printf("Found Node with data: %d\n", foundNode->data);} else {printf("Node not found.\n");}head = reverseList(head);printf("Reversed List: ");traverseList(head);return 0;
}
五、总结
单链表是一种灵活且实用的数据结构,通过动态内存分配和简单的插入、删除操作,使得它在许多实际应用中都能发挥重要作用。掌握单链表的基本操作,为深入学习其他数据结构奠定了基础。希望本总结对理解和使用单链表有所帮助。
小习题:
习题1
习题2
习题3
相关文章:

重生之“我打数据结构,真的假的?”--2.单链表(无习题)
C语言中的单链表总结 单链表是一种基础的数据结构,广泛应用于C语言编程中。它由节点组成,每个节点包含数据和指向下一个节点的指针。单链表的优点在于动态内存分配和高效的插入与删除操作。本文将详细探讨单链表的定义、基本操作、应用场景以及相关示例…...

【有啥问啥】视频插帧算法技术原理详解
视频插帧算法技术原理详解 引言 视频插帧(Video Interpolation)技术,作为计算机视觉领域的一项重要应用,旨在通过算法手段在已有的视频帧之间插入额外的帧,从而提升视频的帧率,使其看起来更加流畅。这一技…...
Leetcode148,109以及二者的合并 -> Tencent面试算法题 - 无序双向链表转BST
根源简述 这道题是腾讯在2024/8/30考的一道面试题,整体来说,难度不大,就是代码量稍稍有点儿大,让我们一起来看一下吧 题目描述 整数无序双向链表能否转BST(二叉搜索树),如果能,怎么转…...

【蓝桥杯选拔赛真题77】python计算小球 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析
目录 python计算小球 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python计算小球 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…...

获取Hive表备注
DESCRIBE EXTENDED 表名;先获取Detailed Table Information这行的data_type字段数据,进行正则匹配,拿到表备注,如下: String str ReUtil.get("parameters:\\{(?!.*?\\().*transient_lastDdlTime.*?comment(.*?)\\}&quo…...
10.30学习
一、科学计数法 C语言中的科学计数法主要用于表示非常大或非常小的浮点数,它遵循以下格式: 1. E或e表示指数: 科学计数法中的E或e用来表示“指数”(Exponent)。例如, 1.23e4 或 1.23E4 表示 1.23 * 10^4…...
什么是栈溢出
一、什么是栈溢出 栈溢出(Stack Overflow)就是指在程序运行过程中,往栈里存放的数据超过了栈所能容纳的最大容量,从而导致程序出现异常行为的情况。这就好比一个箱子本来只能装一定数量的物品,硬要往里面塞更多的东西&…...
在linux中arm-linux-gcc和/usr/bin/gcc有啥区别
在Linux中,arm-linux-gcc和/usr/bin/gcc都是编译器,但它们之间存在显著的区别,主要体现在编译目标、使用场景以及编译生成的二进制文件的可执行性上。而软链接则是Linux文件系统中的一种特殊文件类型,用于创建一个文件的别名。 a…...
常用环境部署(二十二)——MySQL的数据库迁移到另一个机器上
1、导出原数据库的数据 mysqldump -u [用户名] -p[密码] [数据库名] > database_dump.sql 命令示例: mysqldump -u root -p123456 wd > /opt/wd.sql 2、在新机器上创建数据库 mysql -u [用户名] -p -e "CREATE DATABASE [新数据库名]" 命令示…...
两台主机只能单方向ping通
可能性比较大的原因时ping不通的那台主机安装了个人防火墙。 在共享上网的机器中,出于安全考虑,大部分主机都安装个人防火墙软件。几乎所有个人防火墙软件默认不允许其他机器ping本机。一般的做法是将来自外部的ICMP请求报文滤掉,对本机出去的…...

redis windows 5.0 下载
Redis 简介 Redis 是一个高性能的 key-value 数据库,广泛应用于缓存、消息队列、实时分析等场景。它支持多种数据结构,如字符串、哈希、列表、集合、有序集合等,并且提供了丰富的操作命令,能够满足各种复杂的数据处理需求。 下载…...

视频转gif怎么转换?6种视频格式转换简单方法分享,附操作截图!
gif动图凭借其简洁而生动的特点,已成为互联网交流中不可或缺的一部分。尽管gif和视频在技术上有所不同,但两者都能以短小的帧展现动作,而gif通常不带声音,具备循环播放的特性。因此,出于创建gif动图、存储更多媒体文件…...

StructRAG简介
StructRAG是一种新型的框架,旨在提升大型语言模型(LLMs)在知识密集型推理任务中的性能。它通过推理时的混合信息结构化机制,根据任务需求以最合适的格式构建和利用结构化知识。 以下是StructRAG的核心组成部分和工作流程ÿ…...
java脚手架系列12-mongoDB
之所以想写这一系列,是因为之前工作过程中有几次项目是从零开始搭建的,而且项目涉及的内容还不少。在这过程中,遇到了很多棘手的非业务问题,在不断实践过程中慢慢积累出一些基本的实践经验,认为这些与业务无关的基本的…...
python四舍五入保留两位小数
在 Python 中,你可以使用内置的 round() 函数来对数字进行四舍五入并保留两位小数。round() 函数有两个参数:要四舍五入的数字和要保留的小数位数。以下是一个简单的示例: # 示例数字 number 3.14159# 四舍五入保留两位小数 rounded_number…...

期权懂|有什么期权交易策略能够稳赚不赔的?
期权小懂小编每日分享期权知识,帮助期权新手及时有效地掌握即市趋势与新资讯! 有什么期权交易策略能够稳赚不赔的? 期权交易具有风险性,没有任何一种策略能够保证稳赚不赔。 以下是一些常见的期权交易策略,虽不能保证盈利&#…...
笔记本脱机状态
先是显示脱机,请尝试其他方法登录 1.按照联想客服,进入高级选项里面,清除两个更新项目,没有卸载成功 2.安装wepe,先是能检测到U盘,但是进不去,然后我淘宝淘帮我做盘,我自己重新装了一…...

Node.js:模块 包
Node.js:模块 & 包 模块module对象 包npm安装包配置文件镜像源 分类 模块 模块化是指解决一个复杂问题时,自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说,模块是可组合、分解和更换的单元。 简单来说,就是把一个…...

油动无人机动力测试台-60公斤级-Flight Stand 60 ICE
产品简介 通过Flight Stand 60 ICE测试台对内燃机和螺旋桨的拉力,扭矩,转速,燃油流量,温度,功率和螺旋桨效率的测量,帮助用户精准地描述和评估其性能参数,以不断地优化和提升燃油动力系统性能。…...

给grasshopper中的python脚本电池加个标签
ghenv.Component.Message test使用python脚本创建的电池,也可以保存起来。 File – Create User Object...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...

快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...