C++手撕单链表及逆序打印

在学习数据结构的过程中,链表是一个非常重要的基础数据结构。今天,我们将通过C++手动实现一个单链表,并添加一个逆序打印的功能,帮助大家更好地理解链表的实现和操作。

一、链表简介

链表是一种线性数据结构,其中每个元素(称为节点)包含数据部分和指向下一个节点的指针。与数组不同,链表的内存空间是动态分配的,因此可以灵活地插入和删除节点,而不需要移动其他元素。

单链表是最简单的链表形式,每个节点只有一个指向下一个节点的指针。

二、单链表的实现

1. 定义链表节点

我们首先定义链表节点的结构。每个节点包含一个整数值和一个指向下一个节点的指针。

#include <iostream>
using namespace std;// 定义链表节点结构
struct ListNode {int val;          // 节点存储的数据ListNode* next;   // 指向下一个节点的指针// 构造函数ListNode(int x) : val(x), next(nullptr) {}
};

2. 定义链表类

接下来,我们定义一个链表类,包含链表的基本操作,如插入、删除和遍历。

class LinkedList {
private:ListNode* head; // 链表的头指针public:// 构造函数LinkedList() : head(nullptr) {}// 析构函数,释放链表内存~LinkedList() {ListNode* current = head;while (current != nullptr) {ListNode* temp = current;current = current->next;delete temp;}}// 插入节点到链表头部void insertAtHead(int value) {ListNode* newNode = new ListNode(value);newNode->next = head;head = newNode;}// 插入节点到链表尾部void insertAtTail(int value) {ListNode* newNode = new ListNode(value);if (head == nullptr) {head = newNode;return;}ListNode* current = head;while (current->next != nullptr) {current = current->next;}current->next = newNode;}// 删除节点void deleteNode(int value) {if (head == nullptr) return; // 链表为空if (head->val == value) {ListNode* temp = head;head = head->next;delete temp;return;}ListNode* current = head;while (current->next != nullptr && current->next->val != value) {current = current->next;}if (current->next != nullptr) {ListNode* temp = current->next;current->next = current->next->next;delete temp;}}// 打印链表void printList() {ListNode* current = head;while (current != nullptr) {cout << current->val << " -> ";current = current->next;}cout << "nullptr" << endl;}// 逆序打印链表void reversePrint(ListNode* node) {if (node == nullptr) return;reversePrint(node->next);cout << node->val << " ";}// 调用逆序打印void reversePrint() {reversePrint(head);cout << endl;}
};

3. 测试链表

我们编写一个简单的测试程序来验证链表的功能,包括插入、删除、正序打印和逆序打印。

int main() {LinkedList list;// 插入节点list.insertAtHead(3);list.insertAtHead(2);list.insertAtHead(1);list.insertAtTail(4);list.insertAtTail(5);// 打印链表cout << "链表内容: ";list.printList();// 逆序打印链表cout << "逆序打印链表: ";list.reversePrint();// 删除节点list.deleteNode(3);cout << "删除节点 3 后的链表: ";list.printList();// 删除头节点list.deleteNode(1);cout << "删除头节点后的链表: ";list.printList();return 0;
}

4. 输出示例

运行上述代码后,输出如下:

链表内容: 1 -> 2 -> 3 -> 4 -> 5 -> nullptr
逆序打印链表: 5 4 3 2 1
删除节点 3 后的链表: 1 -> 2 -> 4 -> 5 -> nullptr
删除头节点后的链表: 2 -> 4 -> 5 -> nullptr

三、逆序打印的实现

逆序打印链表的关键在于递归。我们定义了一个递归函数 reversePrint,它先递归到链表的尾部,然后在回溯过程中打印每个节点的值。这种方法利用了递归的调用栈,自然地实现了逆序打印。

逆序打印函数

void reversePrint(ListNode* node) {if (node == nullptr) return;reversePrint(node->next);cout << node->val << " ";
}

调用逆序打印

void reversePrint() {reversePrint(head);cout << endl;
}

四、总结

通过手动实现单链表,我们不仅加深了对链表数据结构的理解,还学会了如何操作链表节点,包括插入、删除和遍历。此外,逆序打印功能的实现进一步展示了递归在链表操作中的强大作用。

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

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

相关文章

netty中的ChannelPipeline详解

Netty中的ChannelPipeline是事件处理链的核心组件,负责将多个ChannelHandler组织成有序的责任链,实现网络事件(如数据读写、连接状态变化)的动态编排和传播。以下从核心机制、执行逻辑到应用场景进行详细解析: 1. 核心结构与组成 双向链表结构 组成单元:ChannelPipeline…

智能物联网网关策略部署

实训背景 某智慧工厂需部署物联网网关&#xff0c;实现以下工业级安全管控需求&#xff1a; 设备准入控制&#xff1a;仅允许注册MAC地址的传感器接入&#xff08;白名单&#xff1a;AA:BB:CC:DD:EE:FF&#xff09;。协议合规性&#xff1a;禁止非Modbus TCP&#xff08;端口…

前端-vue2核心

官网网址Vue2 安装 — Vue.js 搭建环境 第一种方式&#xff08;刚开是接触Vue&#xff09; 我们看官网&#xff0c;可以直接在script引入vue版本。这里有两个版本&#xff0c;开发版和生产版本。我们两个都下载。 然后创建一个项目&#xff0c;将下载的生产版本和开发版本粘…

【BUG】远程连接阿里云服务器上的redis报错

出现 Redis Client On Error: Error: connect ECONNREFUSED 47.100.XXX.XX:6379 错误&#xff0c;表明 Redis 客户端无法连接到指定的 Redis 服务器&#xff0c;可按以下步骤排查解决&#xff1a; 1. 检查 Redis 服务器是否运行 操作&#xff1a;在 Redis 服务器所在终端执行…

mongodb--用户管理

文章目录 MongoDB 用户管理1. 连接到 MongoDB2. 用户创建2.1 创建管理员用户2.2 创建特定数据库用户2.3 常用内置角色 3. 用户管理操作3.1 查看所有用户3.2 查看特定用户信息3.3 更新用户密码3.4 添加用户角色3.5 移除用户角色3.6 删除用户 4. 权限修改4.1 创建自定义角色4.2 将…

DeepSeek与搜索引擎:AI生成内容如何突破“语义天花板”

一、搜索引擎的“内容饥饿症”与AI的“产能悖论” 2024年&#xff0c;全球每天新增470万篇网络文章&#xff0c;但搜索引擎的索引拒绝率高达68%。这一矛盾的根源在于&#xff1a;算法对“高质量原创”的定义已从“形式独特性”转向“认知增值性”。传统AI生成内容&#xff08;…

YOLO目标检测应用——基于 YOLOv8目标检测和 SAM 零样本分割实现指定目标分割

概述 在当前的计算机视觉领域&#xff0c;目标分割技术正变得越来越重要。市面上有许多分割模型&#xff0c;它们的工作原理大致相似&#xff0c;通常包括收集数据、配置模型以及训练分割模型等步骤。最终目标是实现精确的目标分割。而随着 SAM&#xff08;Segment Anything M…

在Flutter中使用BottomNavigationBar和IndexedStack可以实现一个功能完整的底部导航栏

在Flutter中&#xff0c;使用BottomNavigationBar和IndexedStack可以实现一个功能完整的底部导航栏。BottomNavigationBar用于显示底部的导航按钮&#xff0c;而IndexedStack则用于管理页面的切换&#xff0c;确保每个页面的状态得以保留&#xff08;即页面不会因为切换而重新构…

【10】数据结构的矩阵与广义表篇章

目录标题 二维以上矩阵矩阵存储方式行序优先存储列序优先存储 特殊矩阵对称矩阵稀疏矩阵三元组方式存储稀疏矩阵的实现三元组初始化稀疏矩阵的初始化稀疏矩阵的创建展示当前稀疏矩阵稀疏矩阵的转置 三元组稀疏矩阵的调试与总代码十字链表方式存储稀疏矩阵的实现十字链表数据标签…

微服务篇——SpringCloud

服务注册 Spring Cloud5大组件有哪些&#xff1f; 服务注册和发现是什么意思&#xff1f;Spring Cloud如何实现服务注册发现&#xff1f; nacos与eureka的区别 负载均衡 如何实现负载均衡&#xff1f; Ribbon负载均衡的策略有哪些&#xff1f; 如何自定义负载均衡的策略&…

【小沐杂货铺】基于Three.JS绘制三维数字地球Earth(GIS 、WebGL、vue、react,提供全部源代码)

&#x1f37a;三维数字地球系列相关文章如下&#x1f37a;&#xff1a;1【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;456:OpenGL、glfw、glut&#xff09;第一期2【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;456:OpenGL、glfw、glut&#xff09;第二期3【小沐…

Cursor 在前端需求开发工作流中的应用|得物技术

一、引言 很高兴与大家分享现阶段 Cursor 在我的工作中的使用体验。首先是预期管理&#xff0c;本篇文章不会分享 x 个你可能不知道的小技巧&#xff0c;也不会让你拥有无需自行编码的能力&#xff0c;同时不涉及 Cursor 工程化方面内容。仅仅是围绕个人开发流程中的已有问题&…

PyQt学习记录

PyQt学习记录 要在界面上 创建一个控件&#xff0c;就需要在程序代码中 创建 这个 控件对应类 地一个 实例对象。 在Qt系统中&#xff0c;控件&#xff08;widget&#xff09;是 层层嵌套 的&#xff0c;除了最顶层的控件&#xff0c;其他的控件都有父控件。 几个函数 函数mo…

react: styled-components实现原理 标签模版

styled-components是针对react中一个前端广泛使用的css-in-js样式库B站 利用标签模版 利用ES6中的 标签模版文档标签模板其实不是模板&#xff0c;而是函数调用的一种特殊形式。“标签”指的就是函数&#xff0c;紧跟在后面的模板字符串就是它的参数。 let a 5; let b 10;…

网络安全应急响应之文件痕迹排查:从犯罪现场到数字狩猎的进化论

凌晨3点&#xff0c;某金融企业的服务器突然告警&#xff0c;核心数据库出现未知进程访问。安全团队紧急介入时&#xff0c;攻击者已抹去日志痕迹。在这场与黑客的时间赛跑中&#xff0c;文件痕迹排查成为破局关键。本文将带您深入数字取证的"案发现场"&#xff0c;揭…

多模态大语言模型arxiv论文略读(七)

MLLM-DataEngine: An Iterative Refinement Approach for MLLM ➡️ 论文标题&#xff1a;MLLM-DataEngine: An Iterative Refinement Approach for MLLM ➡️ 论文作者&#xff1a;Zhiyuan Zhao, Linke Ouyang, Bin Wang, Siyuan Huang, Pan Zhang, Xiaoyi Dong, Jiaqi Wang,…

idea插件:AICommit,智能生成Git提交信息

AICommit&#xff1a;智能生成Git提交信息的IDEA插件指南 一、AICommit插件介绍 AICommit是一款专为开发者设计的IntelliJ IDEA插件&#xff0c;它利用人工智能技术自动生成清晰、规范的Git提交信息(Commit Message)。该插件能够分析你的代码变更&#xff0c;理解修改的上下文…

js 拷贝-包含处理循环引用问题

在 JavaScript 中&#xff0c;拷贝对象和数组时需要特别注意&#xff0c;因为对象和数组是引用类型&#xff0c;直接赋值只会复制引用&#xff0c;而不是实际的数据。以下是几种常见的拷贝方法及其应用场景&#xff1a; 1. 浅拷贝&#xff08;Shallow Copy&#xff09; 浅拷贝…

oracle将varchar2 转为clob类型存储。 oracle不支持直接使用sql,将 varchar2 到clob的类型转换,需要下面操作

将一个现有表中的 VARCHAR2 列数据迁移到一个 CLOB 列的过程。以下是对每一步操作的说明&#xff1a; 1. 添加一个新的 CLOB 类型列 首先&#xff0c;向表中添加一个新的 CLOB 类型的列。这个列将用来存储原本的 VARCHAR2 数据。 ALTER TABLE your_table ADD (new_column CL…

Dynamics 365 Business Central Recurring Sales Lines 经常购买销售行 来作 订阅

#D365 BC ERP# #Navision# 前面有节文章专门介绍了BC 2024 Wave 2 支持的更好的Substription & Recurring Billing。 其实在D365 BC ERP中一直有一个比较简单的订阅模块Recrring Sales Lines。本文将介绍一下如何用Recurring Sales Lines来 实施简易的订阅Substription。具…