图解反转链表的4种方法


声明:本文为博主原创文章,未经允许不得转载。如有问题,欢迎指正!

206. 反转链表 (简单)
题目描述:

反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
链接:https://leetcode-cn.com/problems/reverse-linked-list/

方法一:

遍历原链表,把“当前结点”按照头插法添加到新链表中。思路简单,图解略去。

 / /java代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
    ListNode Reverse=null;    / /定义新链表
    ListNode temp=head;       / /temp用于遍历
    while(temp!=null){        
    ListNode cur=new ListNode(temp.val);  / /生成新结点
    if(Reverse==null) Reverse=cur;    / /Reverse为空时直接指向新结点   
    else{             / /Reverse非空时执行头插:   
    ListNode p=Reverse;    / /1.用p标记Reverse(记录头结点)
    Reverse=cur;           / /2.Reverse指向新结点cur (更改头结点) 
    Reverse.next=p;        / /3.新的头结点与之前链表连接
    }
    temp=temp.next;    
    }
    return Reverse;
    }
}
方法二:

== 双指针解法== 既然是反转,就把原来的“指向”反过来。遍历链表,把当前结点cur指向cur的上一个结点,因为单向链表不能“由当前结点知道上一个结点”,故用pre记录前一个结点。如果只有前面的操作,那cur原本的后继结点就找不到了,故应该先用record将其保存。

/ /java代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur=head;   / /cur用于遍历链表
ListNode pre=null;/ /pre为当前结点cur的上一个结点。初始化为null,因为最开始的pre最终变为尾
while(cur!=null){
ListNode record=cur.next; / /1.记录cur的下一个结点,以防在 cur.next=pre 后找不到“原来的下一个”
    cur.next=pre;         / /2.当前的“指针”指向上一个
    pre=cur;              / /3.pre后移
    cur=record;           / /4.cur指向下一个结点
    } 
    return pre;
    }
}
方法二图解

以下是链表为1->2->3->4->null 时具体的双指针操作过程示例:
在这里插入图片描述

方法三:

迭代法

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
    ListNode cur=head;
    if(head==null) return null;
    while(head.next!=null){
    ListNode record=head.next.next;
    head.next.next=cur;
    cur=head.next;
    head.next=record;

    }
    return cur;

    }
}
方法三图解

以下是链表为1->2->3->4->null 时具体的迭代过程示例:
在这里插入图片描述

方法四:

递归解法:递归解法可由迭代演化过来。(大部分迭代和递归都可以相互转化)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
    if(head==null||head.next==null)  return  head;
    ListNode newHead=reverseList(head.next);
    head.next.next=head;      
    head.next=null;
    return newHead;
    }
}
方法四图解

以下是链表为1->2->3->4->null 时主要的调用和回退过程(橙色结点为递归或回退到的“当前结点”):
在这里插入图片描述

上一篇博客:leetcode 78 子集 (位运算)

首先,让我们先了解一下什么是双向链表。在双向链表中,每个节点都有两个指针,一个指向前一个节点,一个指向后一个节点。这样,在链表中,我们可以从任何一个节点开始,向前或向后遍历整个链表。 接下来,我们来看一下如何反转一个双向链表。 假设我们有一个双向链表如下所示: ``` 1 <-> 2 <-> 3 <-> 4 <-> 5 ``` 我们需要将它反转成: ``` 5 <-> 4 <-> 3 <-> 2 <-> 1 ``` 实现双向链表反转方法如下: ``` public class DoublyLinkedList { // 双向链表节点 private static class Node { int data; Node prev; Node next; Node(int data) { this.data = data; } } // 反转双向链表 public static Node reverse(Node head) { Node temp = null; Node current = head; // 遍历整个链表 while (current != null) { // 交换当前节点的前驱和后继 temp = current.prev; current.prev = current.next; current.next = temp; // 移动到下一个节点 current = current.prev; } // 如果链表不为空,更新头节点 if (temp != null) { head = temp.prev; } return head; } // 测试 public static void main(String[] args) { Node head = new Node(1); head.next = new Node(2); head.next.prev = head; head.next.next = new Node(3); head.next.next.prev = head.next; head.next.next.next = new Node(4); head.next.next.next.prev = head.next.next; head.next.next.next.next = new Node(5); head.next.next.next.next.prev = head.next.next.next; Node reversedHead = reverse(head); while (reversedHead != null) { System.out.print(reversedHead.data + " "); reversedHead = reversedHead.next; } } } ``` 在上面的代码中,我们首先定义了一个 `Node` 类来表示双向链表的节点。然后,我们实现了 `reverse` 方法反转双向链表。在这个方法中,我们使用了一个 `temp` 变量来保存当前节点的前驱节点,然后交换当前节点的前驱节点和后继节点,最后将当前节点移动到下一个节点。最后,我们判断链表是否为空,如果不为空,更新头节点。最后,我们在 `main` 方法中创建了一个双向链表,并调用了 `reverse` 方法反转链表。最后,我们遍历反转后的链表并输出结果。 希望这个解释和代码可以帮助你理解如何反转双向链表
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值