链表的创建:头插法与尾插法详解(数据结构)
C++ 链表的创建:头插法与尾插法详解

链表(Linked List)是一种重要的数据结构,适用于插入和删除操作频繁的场景。本文介绍 两种常见的链表构建方法:
- 尾插法(Append / Tail Insertion):适合顺序存储,插入顺序与输入顺序一致。
- 头插法(Prepend / Head Insertion):适合逆序存储,输入的元素会被倒序存入链表。
本文提供详细的代码实现、解析以及常见错误分析,帮助初学者理解链表的构建方式。
一、链表的基本结构
在 C++ 语言中,我们通常使用结构体(struct)定义链表节点:
#include <iostream>typedef struct Node {int data; // 数据域struct Node* next; // 指针域,指向下一个节点
} Node, *LinkList;
data:存储节点数据。next:存储指向下一个节点的指针。LinkList是Node*的别名,表示指向链表头部的指针。
二、尾插法(顺序存储)
尾插法 是 按照输入顺序 依次插入新节点,适用于按 自然顺序 存储数据。
核心思路:
- 创建头节点 作为链表的起点。
- 维护一个尾指针
r,用于记录链表末尾,以便快速添加新节点。 - 每次创建一个新节点,将其链接到尾指针
r,然后更新r指向新节点。
✅ 尾插法代码实现
#include <iostream>
#include <cstdlib> // malloc 需要包含此头文件typedef struct Node {int data;struct Node* next;
} Node, *LinkList;// 初始化链表(带头结点)
void Init(LinkList &L) {L = (Node*)malloc(sizeof(Node));L->next = NULL;
}// 尾插法插入元素
void InsertTail(LinkList &L, int e) {Node* r = L; // 记录链表尾部Node* s;while (e != -1) { // 以 -1 作为输入结束标志s = (Node*)malloc(sizeof(Node));s->data = e;s->next = NULL;r->next = s; // 连接新结点r = s; // 更新尾指针std::cin >> e; // 读取下一个数据}
}// 打印链表
void PrintL(LinkList &L) {Node* p = L->next; // 跳过头结点if (!p) {std::cout << "Empty List\n";return;}while (p) {std::cout << p->data << " -> ";p = p->next;}std::cout << "NULL\n";
}// 释放链表
void FreeList(LinkList &L) {Node* p = L;while (p) {Node* temp = p;p = p->next;free(temp);}L = NULL;
}int main() {LinkList L;Init(L);int e;std::cin >> e;InsertTail(L, e);PrintL(L);FreeList(L);return 0;
}
📌 示例输入
1 2 3 4 -1
📌 示例输出
1 -> 2 -> 3 -> 4 -> NULL
三、头插法(逆序存储)
头插法 是 逆序存储输入数据,新节点总是插入到链表头部,适用于从后往前访问数据的场景。
核心思路:
- 创建头节点 作为链表的起点。
- 每次创建一个新节点,让其
next指向头节点L的next,然后L->next指向新节点。 - 这样每次新插入的节点都位于链表头部,最终形成逆序链表。
✅ 头插法代码实现
#include <iostream>
#include <cstdlib>typedef struct Node {int data;struct Node* next;
} Node, *LinkList;// 初始化链表(带头结点)
Node* InitL(LinkList &L) {L = (Node*)malloc(sizeof(Node));L->next = NULL;return L;
}// 头插法插入元素
void InsertNext(LinkList &L, int e) {while (e != 9999) { // 以 9999 作为输入结束标志Node* p = (Node*)malloc(sizeof(Node));p->data = e;p->next = L->next; // 让新节点指向头结点的下一个节点L->next = p; // 头结点指向新插入的节点std::cin >> e; // 读取下一个数据}
}// 打印链表
void PrintL(LinkList &L) {Node* p = L->next;if (!p) {std::cout << "Empty List\n";return;}while (p) {std::cout << p->data << " -> ";p = p->next;}std::cout << "NULL\n";
}// 释放链表
void FreeList(LinkList &L) {Node* p = L;while (p) {Node* temp = p;p = p->next;free(temp);}L = NULL;
}int main() {LinkList L;InitL(L);int e;std::cin >> e;InsertNext(L, e);PrintL(L);FreeList(L);return 0;
}
📌 示例输入
1 2 3 4 5 6 9999
📌 示例输出
6 -> 5 -> 4 -> 3 -> 2 -> 1 -> NULL
四、尾插法 vs. 头插法
| 方法 | 适用场景 | 特点 | 代码复杂度 |
|---|---|---|---|
| 尾插法 | 顺序存储 数据 | - 适用于队列、链表等结构。 - 插入顺序与输入顺序一致。 - 插入操作需要维护尾指针 r。 | 适中 |
| 头插法 | 逆序存储 数据 | - 适用于栈、回溯等结构。 - 输入数据被倒序存储。 - 插入操作比尾插法简单,始终修改 L->next。 | 更简单 |
🔹 总结
- 尾插法:适合 顺序存储,需要维护
r指针,但顺序符合直觉。 - 头插法:适合 逆序存储,插入操作更简单,但最终数据顺序颠倒。
- 二者的选择 取决于数据使用的需求,如:
- 队列(FIFO) 适合尾插法。
- 栈(LIFO) 适合头插法。
如果你是初学者,建议多尝试不同方法,以便深入理解链表的操作方式! 🎯
相关文章:
链表的创建:头插法与尾插法详解(数据结构)
C 链表的创建:头插法与尾插法详解 链表(Linked List)是一种重要的数据结构,适用于插入和删除操作频繁的场景。本文介绍 两种常见的链表构建方法: 尾插法(Append / Tail Insertion):…...
MyBatis中mapper.xml 的sql映射规则
一、SQL 映射文件核心元素 MyBatis 映射文件的顶级元素(按定义顺序): cache:命名空间的缓存配置。cache-ref:引用其他命名空间的缓存。resultMap:自定义结果集映射。sql:可重用的 SQL 片段。i…...
深入解析 Java 类加载机制及双亲委派模型
🔍 Java的类加载机制是确保应用程序正确运行的基础,特别是双亲委派模型,它通过父类加载器逐层加载类,避免冲突和重复加载。但在某些特殊场景下,破坏双亲委派模型会带来意想不到的效果。本文将深入解析Java类加载机制、…...
糖尿病大模型预测及临床应用研究智能管理系统技术文档
目录 1. 数据工程规范1.1 多源数据集成1.2 特征工程架构 2. 核心模型架构2.1 分层预测网络2.2 动态血糖预测模块 3. 实时决策系统3.1 术中预警协议3.2 麻醉方案优化器 4. 验证体系实现4.1 数字孪生验证平台4.2 临床验证流程 5. 系统部署方案5.1 边缘计算架构5.2 性能指标 6. 安…...
MySQL数据库精研之旅第四期:解锁库操作高阶技能
专栏:MySQL数据库成长记 个人主页:手握风云 目录 一、查看所有表 1.1. 语法 二、创建表 2.1. 语法 2.2. 示例 2.3. 表在磁盘上对应的⽂件 三、查看表结构 3.1. 语法 3.2. 示例 四、修改表 4.1. 语法 4.2. 示例 五、删除表 5.1. 语法 5.2.…...
【DevOps】DevOps and CI/CD Pipelines
DevOps 是一种将开发与运维实践相结合的模式,旨在缩短软件开发周期并交付高质量软件。 DevOps 是什么? 开发团队与运维团队之间的协作 • 持续集成与持续交付(CI/CD) • 流程自动化 • 基础设施即代码(IaC)…...
Oracle详解
Oracle 数据库是一款由 Oracle 公司开发和维护的关系数据库管理系统(RDBMS)。Oracle 数据库广泛应用于企业级应用中,尤其是在需要高可用性、高性能和安全性的场景。以下是对 Oracle 数据库的详细介绍,包括它的各个方面。 一、Ora…...
VS自定义静态库并在其他项目中使用
1、VS创建一个空项目或者静态库项目 2、右键项目 属性 修改生成文件类型 3、生成解决方案 4、复制.h文件和.lib文件作为静态库 5、创建一个新项目 测试使用新生成的静态库 在新项目UseStaticLib中加一个新文件夹lib,lib中放入上面的.h和.lib文件。 6、vs中右…...
5G AAU(Active Antenna Unit)详细介绍
5G AAU(Active Antenna Unit)详细介绍 1. 定义与架构 5G AAU(Active Antenna Unit,有源天线单元)是5G无线基站系统中的核心组件,它集成了射频(RF)和天线功能,是4G时代R…...
力扣32.最长有效括号(栈)
32. 最长有效括号 - 力扣(LeetCode) 代码区: #include<stack> #include<string> /*最长有效*/ class Solution { public:int longestValidParentheses(string s) {stack<int> st;int ans0;int ns.length();st.push(-1);fo…...
【计算机网络中的奈氏准则与香农定理】
文章目录 一、前言二、奈氏准则1. 概念2. 奈氏准则公式3. 奈氏准则的意义 三、香农定理1. 概念2. 香农定理公式3. 香农定理的意义 四、奈氏准则与香农定理的对比五、应用示例1. 奈氏准则示例2. 香农定理示例 六、总结 一、前言 在计算机网络中,数据的传输速率与信道…...
vue3 项目中预览 word(.docx)文档方法
vue3 项目中预览 word(.docx)文档方法 通过 vue-office/docx 插件预览 docx 文档通过 vue-office/excel 插件预览 excel 文档通过 vue-office/pdf 插件预览 pdf 文档 安装插件 npm install vue-office/docx vue-demi示例代码 <template><Vu…...
DHCP(Dynamic Host Configuration Protocol)原理深度解析
目录 一、DHCP 核心功能 二、DHCP 工作流程(四阶段) 三、关键技术机制 1. 中继代理(Relay Agent) 2. Option 82(中继信息选项) 3. 租期管理 4. 冲突检测 四、DHCP 与网络架构交互 1. MLAG 环境 2.…...
创建login.api.js步骤和方法
依次创建 login.api.js、home.api.js...... login.api.js、home.api.js 差不多 导入到 main.js main.js 项目中使用...
基于springboot二手交易平台(源码+lw+部署文档+讲解),源码可白嫖!
摘要 人类现已迈入二十一世纪,科学技术日新月异,经济、资讯等各方面都有了非常大的进步,尤其是资讯与网络技术的飞速发展,对政治、经济、军事、文化等各方面都有了极大的影响。 利用电脑网络的这些便利,发展一套二手交…...
帕金森患者的生活重塑:从 “嘴” 开启康复之旅
当提到帕金森病,许多人会联想到震颤、僵硬和行动迟缓等症状。这种神经系统退行性疾病,给患者的生活带来了巨大的挑战。然而,你可知道,帕金森患者恢复正常生活,可以从 “嘴” 开始管理? 帕金森病在全球影响着…...
相生、相克、乘侮、复杂病机及对应的脏腑功能联系
一、五行相生关系(母子关系) 五行生序脏腑关系生理表现举例木生火肝(木)滋养心(火)肝血充足则心血旺盛火生土心(火)温煦脾(土)心阳充足则脾胃运化功能正常土…...
鸿蒙OS 5 架构设计探秘:从分层设计到多端部署
文章目录 鸿蒙OS架构设计探秘:从分层设计到多端部署一、鸿蒙的分层架构设计二、模块化设计的精髓三、智慧分发设计:资源的动态调度四、一次开发,多端部署的实践总结与思考 鸿蒙OS架构设计探秘:从分层设计到多端部署 最近两年来&a…...
5. 实现一个中间件
原文地址: 实现一个中间件 更多内容请关注:php代码框架 理解中间件 中间件(Middleware) 是一种在请求被路由到控制器方法之前或响应返回客户端之前执行的代码。它通常用于处理通用任务,如身份验证、日志记录、CORS 处理等。 在…...
JVM 为什么不使用引用计数算法?——深入解析 GC 策略
在 Java 中,垃圾回收(Garbage Collection, GC)是一个至关重要的功能,它能够自动管理内存,回收不再使用的对象,从而防止内存泄漏。然而,在垃圾回收的实现上,JVM 并未采用引用计数算法…...
【HarmonyOS NEXT】EventHub和Emitter的使用场景与区别
一、EventHub是什么? 移动应用开发的同学应该比较了解EventHub,类似于EventBus。标准的事件广播通知,订阅,取消订阅的处理。EventHub模块提供了事件中心,提供订阅、取消订阅、触发事件的能力。 类似的框架工具有很多…...
01-系统编程
一、程序和进程的区别: window系统: 1、程序存储在硬盘中,文件格式为.exe后缀,静态的 2、进程运行在内存中,动态的 Linux系统 1、程序存储在硬盘中,文件格式为.ELF(可执行的链接文件&#…...
Linux编译器gcc/g++使用完全指南:从编译原理到动静态链接
一、gcc/g基础认知 在Linux开发环境中,gcc和g是我们最常用的编译器工具: gcc:GNU C Compiler,专门用于编译C语言程序g:GNU C Compiler,用于编译C程序(也可编译C语言) 📌…...
UMI-OCR Docker 部署
额外补充 Docker 0.前置条件 部署前,请检查主机的CPU是否具有AVX指令集 lscpu | grep avx 输出如下即可继续部署 Flags: ... avx ... avx2 ... 1.下载dockerfile wget https://raw.githubusercontent.com/hiroi-sora/Umi-OCR_runtime_linux/main/Do…...
26考研|数学分析:定积分及应用
这一部分作为数学分析的灵魂,在数学分析的计算中,绝大部分的问题都可以转换成定积分的计算问题,所以在这部分的学习中,一定要注意提升计算能力,除此之外,由积分引出的相关积分不等式也是分析的重点和难点&a…...
React Hooks使用方法:useState,useRef,useEffect,useReducer,useContext用法实战案例
react hooks介绍,包括了state,ref,effect,reducer,context等常见hooks,也包括forwardRef和createContext用法,下面看代码吧,我用的是js写的。每个hook都做了个案例。 // 使用state来…...
线程池详解:在SpringBoot中的最佳实践
线程池详解:在SpringBoot中的最佳实践 引言 在Java并发编程中,线程池是一种非常重要的资源管理工具,它允许我们在应用程序中有效地管理和重用线程,从而提高性能并降低资源消耗。特别是在SpringBoot等企业级应用中,正…...
扩展卡尔曼滤波
1.非线性系统的线性化 标准卡尔曼滤波 适用于线性化系统,扩展卡尔曼滤波 则扩展到了非线性系统,核心原理就是将非线性系统线性化,主要用的的知识点是 泰勒展开(我另外一篇文章的链接),如下是泰勒展开的公式…...
AI作为学术评审专家有哪些优缺点?
大家好这里是AIWritePaper官方账号,官网👉AIWritePaper论文完成初稿之后,一般情况下,宝子们还需要找专家给我们提出评审意见。找专家评审其实并不容易,即使对老师来说,找人评审论文也是一件苦活。我们这个时…...
微信小程序登录和获取手机号
目录 准备工作 实现流程 实现代码 公共部分 通过code获取openid等信息 解密手机号 扩展 不借助工具类实现解密 借助工具类获取access_token 准备工作 需要小程序账号(可以去微信公众平台创建一个测试号或者正式号) appid:小程序id …...
