Java 实现反转一个链表

news2024/11/17 21:31:27

文章目录

  • 思路
  • 核心四步骤
  • 循环移动
  • 代码实现

思路


翻转指的是改变链表中结点的指向,而不是将它的数据反转。


上图展示出的就是一个反转前的链表,下图展示一个反转后的链表。


根据上图可以看出,结点的地址和数据都没有改变,改变的只是链表结点的指向,更改后的头结点变成了尾结点。

首先要定义一个 cur 变量,让这个变量指向 head 结点 的下一个结点。
接着就是将 head 结点置为空,也就是将 head 结点地址域保存的地址改为 null 即可。


链表中的 head 结点原本保存的是 0x11 这个地址,但是现在改为了 null,表示与后面的结点断开了连接。

cur 这个变量指向的就是 head 结点的下一个结点,由于 head 结点地址域里保存的地址改为 null 就与后面结点断开连接了,此时为了保证 cur 可以成功指向,因此需要先将 cur 移动,然后再改 head 结点的地址域。

接下来要做的就是将 cur 指向的结点和它后面的结点全部移动到 head 结点前面即可。


需要注意的是 如果链表一开始就是空的,直接返回 null即可,因为空的链表无法反转
如果此时的链表只有一个结点,也不需要反转,因为一个结点再怎么反转也没有变化

核心四步骤


核心四步骤分别是 :

1.curNext = cur.next
2.cur.next = head
3.head = cur
4.cur = curNext

先定义的 curNext 始终指向 cur.next,curNext 是为了保证将所有的结点都移动到 head 结点的前面去,实现的一个类似于记录的功能。


先将 cur 结点移动到 head 结点的前面,只需要更改 cur 结点地址域中的保存的地址即可,
接着是将 head 指向 cur 指向的结点。

此时第一个结点就已经移动完成了,但是会发现如果还想要移动其他的结点的话其实是无法实现了。
因为此时原本的 head 结点早与后面的结点断开了连接,此时是无法操作后面剩余结点的。

此时四个核心步骤中的 第一个第四个 就体现出了作用。

首先将定义好的 curNext 指向并且始终指向 cur 结点的下一个结点。


可以看到此时 curNext 就指向了 cur 结点的下一个结点。

接下来就是更改 cur 结点的指向,将它移动到 head 结点的前面。


然后是将 head 指向 cur 指向的位置。


此时当我们打算移动其它结点的时候会发现,只需要将 cur 指向 curNext 即可访问到其他的结点了。
这也就是和心步骤的第四步 cur = curNext


以上过程是把这四个步骤都走了一遍才会产生的结果,想要把所有的结点都移动到完毕,继续按照顺序执行上面的四个步骤即可。

循环移动


想要将所有的结点全部移动完毕,实现一个循环即可,在这个循环里面去重复执行上述的四个步骤。




当重复执行了几次循环之后,会发现此时的 cur 虽仍然是指向了 curNext,但是此时 cur 是为空的。
我们此时又可以发现,链表已经反转完成了,因此循环的判定条件就是当 cur 不为空时就继续执行循环,若 cur 为空,也就是说明此时的链表已经反转成功了,跳出循环返回当前的 head 即可。

代码实现

class MySingleNodeTest {
    static class ListNode{
        public int value;//数据
        public ListNode next;//地址

        public ListNode(int value) {
            this.value = value;
        }
    }
    //设置头结点
    public ListNode head;
    //创建链表
    public void createNode() {
        ListNode listNode1 = new ListNode(12);
        ListNode listNode2 = new ListNode(23);
        ListNode listNode3 = new ListNode(34);
        ListNode listNode4 = new ListNode(45);

        listNode1.next = listNode2;
        listNode2.next = listNode3;
        listNode3.next = listNode4;

        this.head = listNode1;//设置头结点
    }
    // 打印链表
    public void disPlay() {
        ListNode cur = this.head;
        while (cur != null) {
            System.out.print(cur.value + " ");
            cur = cur.next;//cur指向它的下一个
        }
        System.out.println();//换行
    }

    // 反转一个链表
    public ListNode reversalList() {
        // 如果链表是空的
        if (this.head == null) {
            return null;
        }
        // 如果只有一个结点不需要反转
        if (this.head.next == null) {
            return this.head;
        }
        // 创建一个 cur 指向头结点的后一个结点
        ListNode cur = this.head.next;
        // 将头结点置为空
        this.head.next = null;
        // 开始四个步骤移动 cur 和后面的结点
        while (cur != null) {
            ListNode curNext = cur.next;
            cur.next = this.head;
            head = cur;
            cur = curNext;
        }
        // 循环结束反转完成返回头结点即可
        return this.head;
    }
}

public class MySingleNode {

    public static void main(String[] args) {
        MySingleNodeTest mySingleNodeTest = new MySingleNodeTest();
        // 调用方法创建链表
        mySingleNodeTest.createNode();
        // 打印反转之前的链表
        mySingleNodeTest.disPlay();

        // 调用反转方法反转
        mySingleNodeTest.reversalList();
        // 打印反转之后的链表
        mySingleNodeTest.disPlay();
    }
}


(1) 反转之前情况:


可以看到此时 头结点 中的数据是 12,而末尾结点中的数据是 45。

此时对应的链表图解如下图:



(2) 反转之后的情况:


调用反转方法后,可以看到此时头结点中的数据变成了 45,而尾结点变成了 12。
此时说明反转成功了。

此时对应的链表图解如下图:

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

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

相关文章

Java SSM框架基础面试题

一、Spring面试题 1、Spring 在ssm中起什么作用? Spring:轻量级框架作用:Bean工厂,用来管理Bean的生命周期和框架集成。两大核心: 1、IOC/DI(控制反转/依赖注入) :把dao依赖注入到service层,s…

Java SSM框架面试题

sql 中 ${} 和 #{}的区别: #将传入的参数都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #{age},如果传入的值是18,那么解析成sql时的值为order by “18”, 如果传入 age ,则会解析为 order by “age”将传入的参…

6.S081——Lab4——trap lab

0.briefly speaking 这是MIT 6.S081 Fall 2021课程的第四个实验,它是有关陷阱机制的一系列小问题,如果对陷阱机制仍有疑问,可以参考我之前写的其他3篇博客,它们很好地解释了一些背景知识: 用户态陷阱(以系统调用为例…

oracle 19c 部署

安装前的基础环境和用户配置等参考rac部署篇oracle rac部署 一、资源准备 将数据库软件上传解压到oracle的家目录(注意解压后的用户属组) [oraclerac1 ~]$ unzip -d $ORACLE_HOME xxxx.zip 二、在xmanager或者vnc中执行安装 [oraclerac1 db_1]$ ./runInstaller 先安装一个数据…

SSM 框架常见面试题

1 Spring面试题 1、Spring 在ssm中起什么作用? Spring:轻量级框架 作用:Bean工厂,用来管理Bean的生命周期和框架集成。 两大核心:1、IOC/DI(控制反转/依赖注入) :把dao依赖注入到service层,ser…

5.3、Dockerfile内命令

【docker】CMD ENTRYPOINT 区别 终极解读!_绝世好阿狸的博客-CSDN博客 0、上下文路径 $ docker build -t nginx:v3 . # . 是上下文路径,那么什么是上下文路径呢? 上下文路径:指docker在构建镜像时想使用本机的文件,…

缓冲区溢出与防护

目录 一、初识缓冲区溢出 1.1 缓冲区溢出概念 1.2 缓存区 1.3 缓存区溢出的危害 1.4 缓存区溢出事件 二、缓存区溢出攻击 2.1 溢出原理 2.2 典型的寄存器 三、缓存区溢出防御 3.1 缓冲区溢出攻击目标 3.2 缓冲区溢出条件 3.3 缓冲区溢出防范 3.3.1 程序设计过程中…

【后端开发】狂神笔记:Redis进阶

文章目录 1 Redis事务1.1 Redis事务简介1.2 Redis事务操作过程1.2.1 开启事务--->执行事务1.2.2 取消事务(discurd) 1.3 事务错误1.3.1 编译期异常1.3.2 运行时异常 2 Redis实现乐观锁2.1 乐观锁和悲观锁2.2 正常执行2.3 测试异常执行 3 Jedis3.1 导入依赖3.2 编码测试3.2.1…

青翼科技自研模块化互联产品 • 模拟采集FMC子卡【产品资料】

FMC122是一款基于FMC标准规范,实现2路16-bit、1GSPS ADC同步采集,2路16-bit 2.5GSPS DAC同步回放功能子卡模块。该模块遵循VITA57.1标准,可直接与FPGA载卡配合使用,板卡ADC器件采用TI的ADS54J60芯片,该芯片具有两个模拟…

EasyExcel实现execl导入导出

引言 在实际开发中,处理 Excel 文件是一个常见的需求。EasyExcel 是一个基于 Java 的开源库,提供了简单易用的 API,可以方便地读取和写入 Excel 文件。本文将介绍如何使用 EasyExcel 实现 Excel 导入功能,以及一些相关的技巧和注…

java的线程池

一、线程池概念 若不使用线程池,在新创建的线程start()后执行完run()就自动销毁了,造成了资源的浪费。使用线程池可以暂时存储线程。 线程池的主要核心原理: 线程池的代码实现: 注意:在实际开发中线程池并不会关闭&a…

【MySQL】一文带你了解排序检索数据

🎬 博客主页:博主链接 🎥 本文由 M malloc 原创,首发于 CSDN🙉 🎄 学习专栏推荐:LeetCode刷题集! 🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指…

经典电路分析——看看大佬设计或代代人改进的作品——欢迎批评指正

1、TTL反相器 1)输入0.3v a)T1,T2,T4 先分析T1的工作状态:计算ube1和uce1 ube1大于开启电压,所以ube10.7v。 因为T2,T4要想导通,V1b上需要有打通三个PN结的能力,也就是说V1b3*0.…

【UE 从零开始制作坦克】3-履带移动效果

目录 一、设置转向灵敏度 二、原地掉头 三、履带移动效果 效果 一、设置转向灵敏度 为了解决坦克转向灵敏度过高的问题,我们首先打开“TankZongLei”蓝图 选中“载具移动(MovementComp)(继承)”将转向输入率中的上…

数据结构图解--队列 的实现/算法+源码

图解--队列 最终的效果接下来 我们要做的就是 使用编程实现这种意识形态下的结构创建队列结构体初始化init进队入队 尾部插入队列的判断满操作出队队列是否为空遍历队列代码的操作交互意识 最终的效果 1.队列的结构形式 队列是一种线性结构 但是特殊的线性结构 只要的特殊在于…

【炫酷登录界面】详解5款高级的前端登录页面及实现源码(附完整源码)

【写在前面】 其实好早之前我就想写这篇文章了,也有些网友还会私信我,说有时候公司要求登录页面的改造,问我能不能出一期关于登录页的文章,于是乎我也是拖到这个时候才整理出来,其实每篇文章的效果内容我都是自己亲自去…

基于51单片机设计的花样流水灯设计

一、项目介绍 花样流水灯是一种常见的LED灯效果,被广泛应用于舞台表演、节日庆典、晚会演出等场合。在现代智能家居、电子产品中,花样流水灯也被广泛使用,通过调整亮灭顺序和时间,可以实现各种炫酷的灯光效果,增强用户体验。而51单片机作为一种常见的嵌入式开发平台,具有…

深搜-剪枝优化

目录 1.问题引入 2.知识讲解 【搜索术语】 (1) *可行性剪枝*: (2) *预处理剪枝*: (3) *重复性剪枝*: (4) *最优性剪枝*: &…

动态规划IV (118、119、198、213、337)

CP118 杨辉三角 题目描述: 给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。在「杨辉三角」中,每个数是它左上方和右上方的数的和。 学习记录: 思想就是没有思想,的杨辉三角,但是注意resiz…

AUTOSAR MCAL之SPI(Specification of SPI Handler/Driver)

本文将详细介绍AUTOSAR MCAL SPI模块的知识点及注意事项,本模块的配置会在其他文章进行分享。本文大部分内容来源于标准,并参照了NXP S32K1系列的 MCAL SPI的代码。 耐心看完本文后,你就对AUTOSAR MCAL SPI有了非常深入的了解。 目录 1. 模…