Java - 反转链表

这篇具有很好参考价值的文章主要介绍了Java - 反转链表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • 目标是反转链表,效果如下:

    反转链表,Java刷算法,java,链表,开发语言

  • 观察要实现以上效果,需要达成什么条件,然后挨个拆解:

    • 需要一个链表
    • 链表遍历
    • 反转函数
    • 测试用例
  • 那么ok,挨个实现以上条件即可

    1.构造链表:链表是一种递归结构,每一个节点除了保存自己的元素之外还有一个指向空或者下一个节点的地址。直白点:
    反转链表,Java刷算法,java,链表,开发语言
    所以链表的节点抽象起来就很简单了:

    private static class Node {
        Integer value;
        Node next;
    
        public Node(Integer value) {
            this.value = value;
        }
    
        @Override
        public String toString() {
            return "Node{" +
                    "value=" + value +
                    ", next=" + next +
                    '}';
        }
    }
    

    之所以用私有静态内部类,主要是节点一般不对外暴露,而是通过操作节点的类提供的api供外部调用,比如虽然我们都知道list内部是个object数组,但也不能直接操作那个数组。

    2.遍历链表:主要是方便验证反转的准确性。

    private static void showLink(Node node) {
        while (node != null) {
            System.out.printf("%d ---> ", node.value);
            node = node.next;
        }
        System.out.printf("%s%n", "null");
    }
    

    3.反转函数,这个是核心,下面逐步分析每行代码的意义:

    private static Node reverse(Node node) {
        Node current = null, prev = null;
    
        while (node != null) {
            current = node;
            node = node.next;
            current.next = prev;
            prev = current;
        }
        return prev;
    }
    

    1)反转最终是要让链表顺序对调,所以对于每个节点操作是一样的,那么首先需要确定循环终止条件,可以借鉴遍历的代码,每次node进入循环的时候其头节点都不一样,所以只要node不为空的时候,则反转的操作要一直继续。
    反转链表,Java刷算法,java,链表,开发语言
    其对应的代码是:

    	while (node != null) {
    		//TODO...
    		node = node.next;
    	}
    

    2)循环体确定之后,那么在每一次循环中,如何将两个相邻节点的指针交换方向成为思考的重点。

  • 做个类比,想象一下有个贪吃蛇每次进入房间(循环体)都会往外面吐出一个方块,我们要将每次吐出来的方块跟上一次吐出来的连接起来,那么需要拿到上一次吐出来的方块和这次吐出来的一共两个方块。

    落地到代码层面,就需要两个指针分别来保存这两个方块的引用,为了区分先后,一个指针叫prev代表前一个方块的引用,current代表当前吐出来的方块。
    对应的代码:

    	Node current = null, prev = null;
    

    3)进行到这一步,就剩交换指针的动作了。核心操作就是让current的next指向prev,动态的变化过程如下:

    反转链表,Java刷算法,java,链表,开发语言

    可以看到node就代表贪吃蛇的头,它每次都吐出一个方块,current和prev分别代表的就是当前和上一个方块,随着node不断吐出方块,current和prev也在一直前进,直到所有的方块都吐出来,这时候prev所代表的链表就是反转之后的。

    对应的代码:

    		current = node;//node吐出的节点交给current,代表这次要处理的节点
            node = node.next;//下一个节点成为蛇头
            current.next = prev;//当前节点的指向改为前一个
            prev = current;//prev向前移动一位
    

    这里的执行顺序是需要注意的点,这行代码

    	node = node.next;//下一个节点成为蛇头
    

    可不是乱放的,因为node将当前节点交给current的时候是把当前链表的头节点地址给了current,两者目前指向的是同一个地址。node是循环条件,负责每次吐出节点的,这时候直接交换就连node指向的对象一起变更了。所以node在交出当前节点的时候就应该立马确定下一次循环的节点位置。

    1. 测试用例,将所有散装的代码合并起来。
    public class ReverseLinkedList {
    
        public static void main(String[] args) {
            Node n1 = new Node(1);
            Node n2 = new Node(2);
            Node n3 = new Node(3);
            Node n4 = new Node(4);
            Node n5 = new Node(5);
            n1.next = n2;
            n2.next = n3;
            n3.next = n4;
            n4.next = n5;
            showLink(n1);
            showLink(reverse(n1));
        }
    
        private static Node reverse(Node node) {
            Node current = null, prev = null;
    
            while (node != null) {
                current = node;
                node = node.next;
                current.next = prev;
                prev = current;
            }
            return prev;
        }
    
        private static void showLink(Node node) {
            while (node != null) {
                System.out.printf("%d ---> ", node.value);
                node = node.next;
            }
            System.out.printf("%s%n", "null");
        }
    
        private static class Node {
            Integer value;
            Node next;
    
            public Node(Integer value) {
                this.value = value;
            }
    
            @Override
            public String toString() {
                return "Node{" +
                        "value=" + value +
                        ", next=" + next +
                        '}';
            }
        }
    }
    

·总结:反转链表是一个比较基础但面试常考的题,思路不难,谁都可以用大白话讲清楚怎么反转,难点在于落地成代码。对于java而言,容易出错的地方是指针对象的应用,值传递的应用,不然很容易出错。文章来源地址https://www.toymoban.com/news/detail-520450.html

到了这里,关于Java - 反转链表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法-设计链表、移除链表元素、反转链表

    伪装成一个老手! 设计一个单链表,其中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。 实现 MyLinkedList 类: MyLinkedList()初始化 MyLinkedList 对象。 int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1

    2024年02月11日
    浏览(95)
  • 【算法手记03】反转链表

    反转链表很重要,是链表题中的高频考点,部分题目可能还需要将反转链表抽出来作为一个函数使用。这几种方式都必须熟练手搓。 lc206.给定单链表头结点,给出反转后的链表。 反转后的新链表带一个dummy结点,将原链表的结点依次插入dummy结点之后,即可完成反转。过程大

    2024年02月19日
    浏览(29)
  • 【算法】链表反转

    给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。 数据范围: 要求:空间复杂度 ,时间复杂度 。 如当输入链表{1,2,3}时, 经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。 每次反转需要修改两个

    2024年02月12日
    浏览(37)
  • 【数据结构和算法】反转链表

    Java基础合集 数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一:迭代(双指针) 2.2 方法二:递归 三、代码 3.1 方法一:迭代(双指针) 3.2 方法二:递归 四、复杂度分析 4.1 方法一:迭代

    2024年01月18日
    浏览(51)
  • 【算法入门&链表】【模板】链表|反转链表|合并排序链表|删除链表的节点

    ✅作者简介:热爱后端语言的大学生,CSDN内容合伙人 ✨精品专栏:C++面向对象 🔥系列专栏:算法百炼成神 本专栏收录的均为牛客网的算法题目,内含链表、双指针、递归、动态规划、基本数据结构等算法思想的具体运用。牛客网不仅有大量的经典算法题目,也有大厂的面

    2024年02月17日
    浏览(58)
  • 数据算法之反转链表(五种方法)

    题目描述 : 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例: 输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1] 提示代码: 这道题来自力扣的第206题,今天我们尝试使用五种不同的方法来实现链表的反转。 第一种方法也是最容易想到的方法,就是将我们链表中的

    2024年02月03日
    浏览(32)
  • 算法通关村第二关——链表反转

    链表反转,就是链表原来是1-2-3-4-5,经过反转处理过后变成5-4-3-2-1 处理链表反转,有两种方式,一个是建立虚拟头结点,一个是直接操作链表反转。  这是执行的流程 最核心的两行就是 直接想我要让她反转,我现在设立了虚拟头结点,那我就要让新加进这个反转链表的结点

    2024年02月13日
    浏览(35)
  • 反转链表的四种方法(C语言)

    206. 反转链表 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1] 示例 2: 输入:head = [1,2] 输出:[2,1] 示例 3: 输入:head = [] 输出:[] 提示: 链表中节点的数目范围是 [0, 5000] -5000 = Node.val = 5000 本题链表不带头结点

    2024年03月20日
    浏览(44)
  • 算法通关村第二关,终于学会反转链表!

    文章目录 一、反转链表 总结 提示:以下是本篇文章正文内容,下面案例可供参考 反转链表主要是用三个指针,一个指针指向空,一个指向head第一个节点,一个在循环做的临时变量,在循环设置这个指针不用考虑head为空的情况,然后在循环改变指向后,向前移动一步,然后

    2024年02月14日
    浏览(46)
  • 算法村第二关(1)——手写链表反转

    题目:Leetcode-206. 反转链表 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表 对于链表反转的问题,想起来其实非常简单。 就是从前往后,将节点一个一个采用头插法的做成一个新链表嘛,这样新链表就是旧链表的反转链表啦! 那既然这么简单,为什么还要学

    2024年02月14日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包