反转链表的Java实现

目录

1、迭代法

2、递归方式


反转链表:

输入:1->2->3->4->5
输出:5->4->3->2->1

1、迭代法

思路:遍历整个链表,当链表不为空时,每次取链表的第一个Node作为当前节点,修改当前Node的指针,重复此步骤,步骤解析如下:

Java代码的具体实现步骤

    public static ListNode reverseNode_1(ListNode node) {
        ListNode previous = null, current, next;
        current = node;
        // 如果当前node不为空,遍历链表
        while (current != null) {
            // 保存当前节点的链接
            next = current.next;
            // 修改当前节点的链接,更改为指向之前的节点
            current.next = previous;

            // 修改之前的节点的值为当前节点
            previous = current;
            // 修改当前节点的值,继续向下遍历
            current = next;
        }
        return previous;
    }

2、递归方式

思路:使用递归,需要满足递归需要的条件

(1)终止递归的条件:当Node为空,或者Node.next为空(只有一个节点),则递归终止,返回当前Node

(2)终止递归的处理方法:return 当前 Node

(3)重复逻辑:修改当前节点下一个节点的指针->指向当前节点;当前节点的指针指向Null

所以,递归的流程入下:重复把当前节点下一个节点的指针->指向当前节点;然后把当前节点的指针指向Null(破环)

Java代码的实现如下:

    public static ListNode reverseNode_2(ListNode node) {
        // 终止条件和终止方法
        if (node == null || node.next == null) {
            return node;
        }
        // 把node替换为node.next继续向下寻找
        ListNode new_node = reverseNode_2(node.next);
        // 反转指针:每一个节点都执行此操作
        node.next.next = node;
        // 不用担心断开,因为后续步骤都会为node.next赋值,当前步骤保持为null就好
        node.next = null;
        return new_node;
    }

下边,对于递归具体的步骤,给出详细的步骤说明:

首先,当递归到节点(5)时,因为(5)的下一个节点是Null,所以 5->Null 会直接返回,当递归到节点(4)时,此时当前节点为 4->5->Null ,在此节点指针修改之前,new_node 仍旧为 5->Null (前一次递归返回)。

然后,开始修改指针,依次执行下边代码

// 修改(4)的下一个节点(5)的next指针由Null指向(4)
node.next.next = node;
// 修改(4)节点的next指针由(5)指向Null 
node.next = null;

修改后,节点(4)变成了 4->Null,new_node 节点变成 5->4->Null,并且把 new_node 返回,图示如下:

重复以上步骤,直到结束递归。

完整的Java代码如下

/**
 * @author swadian
 * @date 2022/5/8
 * @Version 1.0
 * @describetion 反转链表
 */
public class ReverseListNode {
    // 链表
    static class ListNode {
        int val; // value值
        ListNode next; // 指针
        public ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }
        @Override
        public String toString() {
            return "(" + val + "-> " + next + ')';
        }
    }

    /**
     * 输入:1-2-3-4-5
     * 输出:5-4-3-2-1
     */
    public static void main(String[] args) {
        ListNode listNode = prepareListNode();
        ListNode node1 = reverseNode_1(listNode);
        ListNode node2 = reverseNode_2(listNode);
    }

    /**
     * 迭代思想
     * 输入:1-2-3-4-5 : (1,->2),(2,->3),(3,->4),(4,->5),(5,->null)
     * 输出:5-4-3-2-1 : (5,->4),(4,->3),(3,->2),(2,->1),(1,->null)
     */
    public static ListNode reverseNode_1(ListNode node) {
        ListNode previous = null, current, next;
        current = node;
        // 如果当前node不为空,遍历链表
        while (current != null) {
            // 保存当前节点的链接
            next = current.next;
            // 修改当前节点的链接,更改为指向之前的节点
            current.next = previous;
            // 修改之前的节点的值为当前节点
            previous = current;
            // 修改当前节点的值,继续向下遍历
            current = next;
        }
        return previous;
    }

    // 递归
    public static ListNode reverseNode_2(ListNode node) {
        // 终止条件和终止方法
        System.out.println(node);
        if (node == null || node.next == null) {
            return node;
        }
        // 把node替换为node.next继续向下寻找
        ListNode new_node = reverseNode_2(node.next);
        // 反转指针:每一个节点都执行此操作
        node.next.next = node;
        // 不用担心断开,因为后续步骤都会为node.next赋值,当前步骤保持为null就好
        node.next = null;
        return new_node;
    }
    
    public static ListNode prepareListNode() {
        ListNode node5 = new ListNode(5, null);
        ListNode node4 = new ListNode(4, node5);
        ListNode node3 = new ListNode(3, node4);
        ListNode node2 = new ListNode(2, node3);
        ListNode node1 = new ListNode(1, node2);
        return node1;
    }
}
  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

swadian2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值