链表逆序用哨兵位头节点

在C语言中实现链表的逆序,使用哨兵头节点是一种常见的做法。哨兵头节点可以简化代码逻辑,特别是当链表为空时,可以避免空指针异常。下面是一个使用哨兵头节点逆序单链表的C语言实现

示例:

#include <stdio.h>
#include <stdlib.h>// 定义链表节点结构体
typedef struct ListNode {int val;struct ListNode *next;
} ListNode;// 创建新节点
ListNode* createNode(int value) {ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));if (!newNode) {exit(-1); // 分配内存失败,退出程序}newNode->val = value;newNode->next = NULL;return newNode;
}// 逆序链表,使用哨兵头节点
void reverseList(ListNode** headRef) {ListNode* prev = NULL;ListNode* current = *headRef;ListNode* next = NULL;while (current != NULL) {next = current->next;  // 保存下一个节点current->next = prev;  // 当前节点指向前一个节点,实现逆序prev = current;        // 前一个节点移动到当前节点current = next;        // 当前节点移动到下一个节点}*headRef = prev;  // 更新头节点
}// 打印链表
void printList(ListNode* head) {ListNode* temp = head;while (temp != NULL) {printf("%d ", temp->val);temp = temp->next;}printf("\n");
}// 主函数,测试逆序链表功能
int main() {ListNode* head = createNode(1);head->next = createNode(2);head->next->next = createNode(3);head->next->next->next = createNode(4);printf("原始链表:");printList(head);reverseList(&head);printf("逆序后链表:");printList(head);// 释放链表内存ListNode* temp;while (head != NULL) {temp = head;head = head->next;free(temp);}return 0;
}

在这个代码中,我们首先定义了链表节点的结构体ListNode,然后提供了创建新节点的函数createNodereverseList函数用来逆序链表,它使用了一个哨兵头节点,即第一个节点作为prev指针的初始位置,最后将头节点更新为prev指针所指向的节点。printList函数用来打印链表的节点值。

main函数中,我们创建了一个简单的链表,并调用reverseList函数进行逆序,然后打印出逆序后的结果。最后,我们释放了链表占用的内存。

请注意,在实际的项目开发中,还需要对代码进行适当的错误处理和边界条件检查,以确保程序的健壮性。

在C语言中,使用哨兵位头节点(dummy head)来逆序链表是一种常见的技巧,因为它可以简化边界条件的处理。以下是一个使用哨兵位头节点逆序单链表的示例代码:

// 链表节点的结构体定义

typedef struct ListNode {int val;struct ListNode *next;
} ListNode;

// 创建一个新的链表节点

ListNode* createNode(int value) {ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));if (!newNode) {exit(-1); // 分配内存失败,退出程序}newNode->val = value;newNode->next = NULL;return newNode;
}

// 在链表的末尾添加一个新节点

void appendNode(ListNode** headRef, int value) {ListNode* newNode = createNode(value);ListNode* temp = *headRef;if (temp == NULL) {*headRef = newNode;return;}while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;
}

// 逆序链表,使用哨兵位头节点

void reverseList(ListNode** headRef) {ListNode* prev = NULL;ListNode* current = *headRef;ListNode* next = NULL;while (current != NULL) {next = current->next;  // 保存下一个节点current->next = prev;  // 当前节点指向前一个节点prev = current;        // 前一个节点移动到当前节点current = next;        // 当前节点移动到下一个节点}*headRef = prev;  // 更新头节点
}

// 打印链表

void printList(ListNode* head) {ListNode* temp = head;while (temp != NULL) {printf("%d ", temp->val);temp = temp->next;}printf("\n");
}

// 主函数,测试逆序链表功能

int main() {ListNode* head = NULL; // 哨兵位头节点// 向链表中添加元素appendNode(&head, 1);appendNode(&head, 2);appendNode(&head, 3);appendNode(&head, 4);printf("原始链表:");printList(head);// 逆序链表reverseList(&head);printf("逆序后链表:");printList(head);// 释放链表内存ListNode* temp;while (head != NULL) {temp = head;head = head->next;free(temp);}return 0;
}

总代码

#include <stdio.h>
#include <stdlib.h>// 链表节点的结构体定义
typedef struct ListNode {int val;struct ListNode *next;
} ListNode;// 创建一个新的链表节点
ListNode* createNode(int value) {ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));if (!newNode) {exit(-1); // 分配内存失败,退出程序}newNode->val = value;newNode->next = NULL;return newNode;
}// 在链表的末尾添加一个新节点
void appendNode(ListNode** headRef, int value) {ListNode* newNode = createNode(value);ListNode* temp = *headRef;if (temp == NULL) {*headRef = newNode;return;}while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;
}// 逆序链表,使用哨兵位头节点
void reverseList(ListNode** headRef) {ListNode* prev = NULL;ListNode* current = *headRef;ListNode* next = NULL;while (current != NULL) {next = current->next;  // 保存下一个节点current->next = prev;  // 当前节点指向前一个节点prev = current;        // 前一个节点移动到当前节点current = next;        // 当前节点移动到下一个节点}*headRef = prev;  // 更新头节点
}// 打印链表
void printList(ListNode* head) {ListNode* temp = head;while (temp != NULL) {printf("%d ", temp->val);temp = temp->next;}printf("\n");
}// 主函数,测试逆序链表功能
int main() {ListNode* head = NULL; // 哨兵位头节点// 向链表中添加元素appendNode(&head, 1);appendNode(&head, 2);appendNode(&head, 3);appendNode(&head, 4);printf("原始链表:");printList(head);// 逆序链表reverseList(&head);printf("逆序后链表:");printList(head);// 释放链表内存ListNode* temp;while (head != NULL) {temp = head;head = head->next;free(temp);}return 0;
}

在这个代码中,我们首先定义了链表节点的结构体ListNode。然后,我们提供了创建新节点和向链表末尾添加新节点的函数createNodeappendNodereverseList函数用来逆序链表,它使用了一个哨兵头节点prev,并最终将头节点更新为prev指针所指向的节点。printList函数用来打印链表的节点值。

main函数中,我们创建了一个链表,并调用reverseList函数进行逆序,然后打印出逆序后的结果。最后,我们释放了链表占用的内存。

请注意,在实际的项目开发中,还需要对代码进行适当的错误处理和边界条件检查,以确保程序的健壮性。

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

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

相关文章

富格林:应用正规技巧阻挠被骗

富格林悉知&#xff0c;随着如今入市现货黄金的朋友愈来愈多&#xff0c;不少投资者也慢慢开始重视起提高自身的正规投资技巧&#xff0c;希望能阻挠被骗更高效地在市场上获利。虽然目前黄金市场存在一定的受害风险&#xff0c;但只要投资者严格按照正规的交易规则来做单&#…

python解决flask启动的同时启动定时任务

业务场景描述&#xff1a;在常规的开发中&#xff0c;我们开发接口服务&#xff0c;一般会将数据放在数据库、文件等第三方文件&#xff0c;启动服务后&#xff0c;服务到后台数据库中加载数据&#xff0c;这样做的好处当然是开发会更加便利以及数据的可复用性较高&#xff0c;…

深度学习-03-函数的连续调用

深度学习-03-函数的连续调用 本文是《深度学习入门2-自製框架》 的学习笔记&#xff0c;记录自己学习心得&#xff0c;以及对重点知识的理解。如果内容对你有帮助&#xff0c;请支持正版&#xff0c;去购买正版书籍&#xff0c;支持正版书籍不仅是尊重作者的辛勤劳动&#xff0…

LLaMA-Factory推理实践

运行成功的记录 平台&#xff1a;带有GPU的服务器 运行的命令 git clone https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory/ conda create -n py310 python3.10 conda activate py310由于服务器不能直接从huggingface上下载Qwen1.5-0.5B&#xff0c;但本地可…

51仿真器 PZ-51Tracker 未知设备

插上仿真器&#xff0c;右击我的电脑 等待一下&#xff0c;选择winUSB 此时在keil中选择仿真器会报错&#xff0c;需要安装如下我是win10) 安装好后退出再试&#xff0c;没有报错即可 这项也要选择 另外配置晶振

MYSQL之存储篇

MYSQL之存储篇 存储过程简介存储过程优点&#xff1a; MySQL的存储过程MySQL存储过程的创建1.格式2.声明分割符3.参数4.变量5.注释6.MySQL存储过程的调用7. MySQL存储过程的查询8.MySQL存储过程的修改9.MySQL存储过程的删除10. MySQL存储过程的控制语句11.MySQL存储过程的基本函…

mybatis配置环境流程

mybatis配置环境流程 为啥要用mybatis&#xff1a;通过Mybatis实现快速访问后端pgsql、mysql等数据库。 1.修改pom.xml&#xff0c;添加mybatis相关依赖 <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-s…

React + SpringBoot开发用户中心管理系统

用户中心项目搭建笔记 技术栈 前端技术栈 “react”: “^18.2.0”,ant-design-pro 后端技术栈 SpringBoot 2.6.x 项目源码地址 https://gitee.com/szxio/user-center 前端项目搭建 快速搭建一个后端管理系统项目框架 初始化 antDesignPro 官网&#xff1a; https://…

Spel表达式使用案例

package com.example.demo.api;import com.example.demo.model.User; import lombok.extern.slf4j.Slf4j;<

CSS Web前端框架:深入剖析与应用实践

CSS Web前端框架&#xff1a;深入剖析与应用实践 在快速发展的Web技术领域&#xff0c;CSS Web前端框架已成为构建现代化、高效且响应式网页的关键工具。它们不仅简化了开发过程&#xff0c;还提高了代码的可维护性和复用性。然而&#xff0c;面对众多纷繁复杂的框架选择&…

ByteBuddy字节码增强器

Byte Buddy是java的字节码增强器&#xff0c;一个优雅的运行时java代码生成库&#xff0c;使用时需要慎重 文档地址&#xff1a;http://bytebuddy.net/#/tutorial-cn 1. 引入ByteBuddy <!-- https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy --><depend…

LeetCode---哈希表

242. 有效的字母异位词 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同&#xff0c;则称 s 和 t 互为字母异位词。 代码示例&#xff1a; //时间复杂度: O(n) //空间复杂度: O(1) c…

Java生成PDF笔记整理

引入依赖, groupId:com.itextpdf, version:8.0.4, artifactId如下kernel,io,layout,forms创建pdf对象try(ByteArrayOutputStream outputStream new ByteArrayOutputStream()){PdfWriter writer new PdfWriter(outputStream, new WriterProperties().setFullCompressionMode(t…

离线安装python库

1. 下载安装包 在联网机器上安装 # 选择符合目标架构的版本&#xff0c;主要是libc版本和python版本 pip download --platformmanylinux2010_x86_64 --only-binary:all: --python-version3.7.4 tabulate # 或者 pip download --platformmanylinux_2_5_x86_64 --only-binary:a…

do...while循环

基本语法 while循环&#xff0c;是先判断条件再执行。 do...while循环&#xff0c;是先斩后奏&#xff0c;先至少执行一次循环语句块中的逻辑&#xff0c;再判断是否继续。 do {//do while 循环语句块; } while (bool类型的值);注意&#xff1a;do...while语句&#xff0c;存…

Common Lisp笔记

在计划学习函数式编程的时候&#xff0c;我一开始打算学习的是 F#。因为我朋友就是在 DTU 上的学&#xff0c;F# 就是 DTU&#xff08;丹麦理工&#xff09;开发的。但是由于 F# 和微软的 .NET 绑定&#xff0c;而在 macOS 上&#xff0c;目前版本的 .NET 的是有些问题的&#…

2020编程语言排序:探索编程界的热门与趋势

2020编程语言排序&#xff1a;探索编程界的热门与趋势 在数字时代的浪潮中&#xff0c;编程语言作为构建数字世界的基石&#xff0c;其流行度和影响力不容忽视。2020年&#xff0c;各大编程语言在各自的领域里展现出独特的魅力和实力。本文将从四个方面、五个方面、六个方面和…

线性代数|机器学习-P3乘法和因式分解矩阵

文章目录 1. 矩阵分解2. S Q Λ Q T SQ\Lambda Q^T SQΛQT3. A U Σ V T AU\Sigma V^T AUΣVT4. A LU 分解5. 矩阵的四个子空间 1. 矩阵分解 目前我们有很多重要的矩阵分解&#xff0c;每个分解对应于多个前提条件&#xff0c;分解方法&#xff0c;分解后的形状会中如下&…

【Vue】v-for中的key

文章目录 一、引入问题二、分析问题 一、引入问题 语法&#xff1a; key属性 "唯一值" 作用&#xff1a;给列表项添加的唯一标识。便于Vue进行列表项的正确排序复用。 为什么加key&#xff1a;Vue 的默认行为会尝试原地修改元素&#xff08;就地复用&#xff09;…

马宝国和沈有容-UMLChina建模知识竞赛第5赛季第12轮

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 参考潘加宇在《软件方法》和UMLChina公众号文章中发表的内容作答。在本文下留言回答。 只要最先答对前3题&#xff0c;即可获得本轮优胜。 如果有第4题&#xff0c;第4题为附加题&am…