Skip to content

反转双向链表

约 625 字大约 2 分钟

2025-03-01

迭代

// 定义双向链表的节点结构
class ListNode {
    int val;
    ListNode next;
    ListNode prev;

    // 构造函数
    ListNode(int val) {
        this.val = val;
        this.next = null;
        this.prev = null;
    }
}

public class Solution {

    // 反转双向链表的函数
    public static ListNode reverseDoublyLinkedList(ListNode head) {
        // 如果链表为空或只有一个节点,直接返回头节点
        if (head == null || head.next == null) {
            return head;
        }

        ListNode current = head;
        // previous类似虚拟节点,真正起作用的是prev。
        ListNode previous = null;

        // 遍历链表并交换每个节点的 prev 和 next 指针
        while (current != null) {
            // 临时保存当前节点的 prev
            ListNode prev = current.prev;
            ListNode next = current.next;

            // 交换 prev 和 next
            current.prev = next;
            current.next = prev;

            // 前进。更新新的头节点为当前节点。注意不是prev。
            previous = current;
            // 移动到下一个节点 (即原来的 prev 节点)
            current = next;
        }

        // 返回新的头节点
        return previous;
    }

    // 打印双向链表的函数
    public static void printDoublyLinkedList(ListNode head) {
        ListNode temp = head;
        while (temp != null) {
            System.out.print(temp.val + " ");
            temp = temp.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
        // 创建双向链表:1 <-> 2 <-> 3 <-> 4
        ListNode node1 = new ListNode(1);
        ListNode node2 = new ListNode(2);
        ListNode node3 = new ListNode(3);
        ListNode node4 = new ListNode(4);

        node1.next = node2;
        node2.prev = node1;
        node2.next = node3;
        node3.prev = node2;
        node3.next = node4;
        node4.prev = node3;

        // 打印原链表
        System.out.print("原链表: ");
        printDoublyLinkedList(node1);

        // 反转链表
        ListNode newHead = reverseDoublyLinkedList(node1);

        // 打印反转后的链表
        System.out.print("反转后的链表: ");
        printDoublyLinkedList(newHead);
    }
}

递归

// 定义双向链表的节点结构
class ListNode {
    int val;
    ListNode next;
    ListNode prev;

    // 构造函数
    ListNode(int val) {
        this.val = val;
        this.next = null;
        this.prev = null;
    }
}

public class Solution {

    // 递归反转双向链表的函数
    public static ListNode reverseDoublyLinkedList(ListNode head) {
        // 基本情况:如果链表为空或只有一个节点,直接返回该节点
        if (head == null || head.next == null) {
            return head;
        }

        // 递归处理下一个节点
        ListNode newHead = reverseDoublyLinkedList(head.next);

        // 交换当前节点的 next 和 prev
        ListNode nextNode = head.next;
        // head.prev是null
        head.next = head.prev;
        head.prev = nextNode;
        
        // 当前节点原本的 next(即现在的 prev)的 next 需要指向当前节点。重点。
        nextNode.next = head;

        return newHead; // 返回新头节点
    }

    // 打印双向链表的函数
    public static void printDoublyLinkedList(ListNode head) {
        ListNode temp = head;
        while (temp != null) {
            // 注意没有ln
            System.out.print(temp.val + " ");
            temp = temp.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
        // 创建双向链表:1 <-> 2 <-> 3 <-> 4
        ListNode node1 = new ListNode(1);
        ListNode node2 = new ListNode(2);
        ListNode node3 = new ListNode(3);
        ListNode node4 = new ListNode(4);

        node1.next = node2;
        node2.prev = node1;
        node2.next = node3;
        node3.prev = node2;
        node3.next = node4;
        node4.prev = node3;

        // 打印原链表
        System.out.print("原链表: ");
        printDoublyLinkedList(node1);

        // 递归反转链表
        ListNode newHead = reverseDoublyLinkedList(node1);

        // 打印反转后的链表
        System.out.print("反转后的链表: ");
        printDoublyLinkedList(newHead);
    }
}