反转链表(java版)

题目描述

输入一个链表,反转链表后,输出新链表的表头。

解题方法

链表示意如下:
a->b->c->d->e->…x->y->z
目标是将链表反转为以 z为头结点的链表。
这里显然需要从前到后遍历整个链表,针对每个节点进行反转操作,以节点“c”为例,假设前面节点已经完成反转,c这时指向“b”,那么c和d之间的联系就断裂了,从而无法继续下去,所以这里也需要事先存储好下一节点,那么也就需要存储三个节点:当前节点,前一个节点,后一个节点。
先以第一个节点“a”为例:
第一步:存储a的下一个节点,设为next=a.next;
第二步:将a的指针指向前一个,这里设置pre=null,a.next=pre,这样正好反转后的链表的尾节点的next为null。
第三部:将指针后移,对“b”操作,这时pre=head,head=next,这样一直到最后“z”,返回“z”即可。

代码

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode ReverseList(ListNode head) {
        if(head == null)
        {
            return null;
        }
        ListNode pre = null;
        ListNode next = null;
        while(head!=null)
        {
            next = head.next; //存储下一节点
            head.next = pre;  //将指针重新指向前面的节点
            
            pre = head;  //将节点往前移动,逐一移动
            head=next;
        }
        return pre;

    }
}
### 链表反转的实现方式 链表是一种线性数据结构,其每个节点包含一个数据元素和指向下一个节点的引用。在 Java 中,链表可以通过自定义类来实现,并且可以通过多种方法对链表进行反转操作。 #### 1. 迭代法实现链表反转 这种方法通过遍历链表并逐个调整节点的指针方向来实现反转。具体步骤如下: - 定义三个指针 `pre`、`current` 和 `next`。 - 初始化 `pre` 为 `null`,`current` 指向头节点。 - 遍历链表时,先保存当前节点的下一个节点到 `next`。 - 将 `current.next` 指向 `pre`,完成指针反转。 - 更新 `pre` 为 `current`,`current` 为 `next`。 - 当 `current` 变为空时,新的头节点为 `pre`。 ```java public class MyLinkedList { private ListNode head = new ListNode(0); // 带头结点的链表 public static class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } // 迭代法反转链表 public ListNode reverseList(ListNode head) { if (head == null || head.next == null) { return head; } ListNode pre = null; ListNode current = head; while (current != null) { ListNode next = current.next; // 保存下一个节点 current.next = pre; // 反转指针 pre = current; // 移动pre current = next; // 移动current } return pre; // 新的头节点 } } ``` #### 2. 递归法实现链表反转 递归方法通过将问题分解为子问题来解决。它会一直递归到最后一个节点,然后逐步反转指针。 - 如果链表为空或只有一个节点,直接返回该节点。 - 递归调用函数处理下一个节点。 - 在回溯过程中,将当前节点的下一个节点的 `next` 指向当前节点。 - 最后将当前节点的 `next` 设为 `null`。 ```java public ListNode reverseList3(ListNode pHead){ if(pHead == null || pHead.next == null){ return pHead; } ListNode pNext = pHead.next; pHead.next = null; ListNode reverseHead = reverseList3(pNext); pNext.next = pHead; return reverseHead; } ``` #### 3. 头插法实现链表反转 头插法是利用一个新的链表头部,每次从原链表中取出一个节点插入到新链表的头部,从而实现反转[^3]。 - 创建一个新的头节点 `reverseHead`。 - 遍历原始链表,将每一个节点插入到 `reverseHead` 的前面。 - 最后将原始头节点的 `next` 指向 `reverseHead.next`。 ```java public static void reverseList(HeroNode head) { if(head.next == null || head.next.next == null) { return; } HeroNode cur = head.next; HeroNode next = null; HeroNode reverseHead = new HeroNode(0, "", ""); while(cur != null) { next = cur.next; cur.next = reverseHead.next; reverseHead.next = cur; cur = next; } head.next = reverseHead.next; } ``` ### 总结 以上三种方法均可以在 Java 中实现链表反转。迭代法适用于大多数情况,代码逻辑清晰;递归法更简洁,但可能会导致栈溢出;头插法则适合需要修改原链表结构的情况。根据实际需求选择合适的方法即可[^1][^2][^3][^4][^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值