Java实现反转一个链表的示例代码

 更新时间:2023年07月04日 16:07:39   作者:与大师约会  
本文主要介绍了Java实现反转一个链表的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

思路

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

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

根据上图可以看出,结点的地址和数据都没有改变,改变的只是链表结点的指向,更改后的头结点变成了尾结点。首先要定义一个 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。此时说明反转成功了。此时对应的链表图解如下图:

 到此这篇关于Java实现反转一个链表的示例代码的文章就介绍到这了,更多相关Java 反转链表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 不知道面试会不会问Lambda怎么用(推荐)

    不知道面试会不会问Lambda怎么用(推荐)

    这篇文章主要介绍了Lambda表达式用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Java代码读取文件缓存问题解决

    Java代码读取文件缓存问题解决

    最近遇到了一个Java文件读取的缓存问题,打远程断点出现的也是原来的老代码参数,本文就介绍一下解决方法,感兴趣的可以了解一下
    2021-05-05
  • Java人机猜拳实现的思路及方法实例

    Java人机猜拳实现的思路及方法实例

    这篇文章主要给大家介绍了关于Java人机猜拳实现的思路及方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • 源码分析Spring 中 @Qualifier 注解基本用法

    源码分析Spring 中 @Qualifier 注解基本用法

    这篇文章主要介绍了源码分析Spring 中 @Qualifier 注解基本用法,在源码分析的过程中,也 GET 到 Spring 许多新的玩法,感兴趣的小伙伴赶紧去试试吧
    2023-08-08
  • 使用@JsonFormat和@DateTimeFormat对Date格式化操作

    使用@JsonFormat和@DateTimeFormat对Date格式化操作

    这篇文章主要介绍了使用@JsonFormat和@DateTimeFormat对Date格式化操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Java中FileOutputStream类的使用

    Java中FileOutputStream类的使用

    java.io.FileOutputStream类是文件输出流,用于将数据写出到文件,下面就来介绍一下Java中FileOutputStream类的使用,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • java中map与实体类的相互转换操作

    java中map与实体类的相互转换操作

    这篇文章主要介绍了java中map与实体类的相互转换操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • java解析背包问题实例代码(简单易懂)

    java解析背包问题实例代码(简单易懂)

    背包问题是计算机科学中的经典问题,涉及到在给定的一组物品中选择最佳的物品组合,以使其总重量不超过背包所能承载的限制,同时获得最大的总价值,这篇文章主要介绍了java解析背包问题的相关资料,需要的朋友可以参考下
    2025-10-10
  • java实现文件打包压缩输出到浏览器下载

    java实现文件打包压缩输出到浏览器下载

    这篇文章主要介绍了java实现文件打包压缩输出到浏览器下载,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • SpringBoot项目中JDK动态代理和CGLIB动态代理的使用详解

    SpringBoot项目中JDK动态代理和CGLIB动态代理的使用详解

    JDK动态代理和CGLIB动态代理都是SpringBoot中实现AOP的重要技术,JDK动态代理通过反射生成代理类,适用于目标类实现了接口的场景,性能较好,易用性高,但必须实现接口且不能代理final方法,CGLIB动态代理通过生成子类实现代理
    2025-03-03

最新评论