反转链表:三种实现思路与细节梳理

反转链表是链表操作中最基础、最经典的问题之一。看似简单,却能很好地体现对指针、递归、边界处理的理解程度。本文从三种不同思路实现反转链表,并对每一种写法的逻辑与细节做完整梳理。

问题描述

206. 反转链表:给你单链表的头节点 head,请将该链表反转,并返回反转后的链表头节点。

方法一:头插法

头插法的思路非常直观:构建一个新链表,依次将原链表的节点插入到新链表头部,最终得到的链表自然是原链表的逆序。

代码

cpp 复制代码
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (head == nullptr || head->next == nullptr)
            return head;

        ListNode* dummy = new ListNode(0, head);
        ListNode* cur = head->next;
        ListNode* next = cur->next;

        head->next = nullptr;

        while (cur != nullptr) {
            cur->next = dummy->next;
            dummy->next = cur;
            cur = next;
            if (next) next = next->next;
        }

        ListNode* res = dummy->next;
        delete dummy;
        return res;
    }
};

特点

  • 思路清晰,容易理解与实现
  • 借助虚拟头节点,统一处理逻辑
  • 时间复杂度 O (n),空间复杂度 O (1)

方法二:三指针迭代法

使用三个指针依次向后遍历,逐个修改节点指向,原地完成反转。这是最常用、最稳健的迭代写法,逻辑紧凑、效率稳定。

代码

cpp 复制代码
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (head == nullptr || head->next == nullptr)
            return head;

        ListNode* prev = head;
        ListNode* cur = head->next;
        ListNode* next = cur->next;

        prev->next = nullptr;

        while (cur != nullptr) {
            cur->next = prev;
            prev = cur;
            cur = next;
            if (next) next = next->next;
        }

        return prev;
    }
};

特点

  • 迭代实现,无栈溢出风险
  • 时间复杂度 O (n),空间复杂度 O (1)
  • 工程中最推荐的写法

方法三:递归实现

递归思路将问题分解为:**先反转后续子链表,再处理当前节点的指向关系。**代码简洁,适合理解递归思想与链表结构。

  • 先递归到链表的最后一个节点,使得newhead记录下反转后的头结点,即原链表的尾结点
  • 然后在 "回溯" 的过程中,逐个修改节点的指向,让每个节点的next指向自己的前一个节点。

代码

cpp 复制代码
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (head == nullptr || head->next == nullptr)
            return head;

        ListNode* newHead = reverseList(head->next);

        head->next->next = head; // 使下一节点指向自己
        head->next = nullptr; // 使自己指向NULL

        return newHead;
    }
};

特点

  • 代码简洁
  • 依靠递归栈实现,空间复杂度 O (n)
  • 适合理解分治思想与链表回溯过程

总结

反转链表虽然基础,但包含了链表操作的核心要点:

  • 边界判断:空链表、单节点链表直接返回
  • 指针移动顺序:避免断链与空指针访问
  • 尾节点必须置空,防止出现环
  • 迭代与递归各有适用场景,可根据需求选择

扎实掌握这几种写法,能为更复杂的链表题目打下坚实基础。

相关推荐
h_a_o777oah10 小时前
【树论】树链剖分:将树形结构转化为线性结构以处理树上路径问题(洛谷 P3384 附C++代码模板)
数据结构·算法·线段树·acm·树链剖分·树论·重链剖分
HEJOO910 小时前
指针的算术运算详解
java·数据结构·算法
Coder-magician10 小时前
《代码随想录》刷题打卡day47:并查集-part01
数据结构·算法·图论
垆边人似月.11 小时前
VLAN 资源池(100~200 分档)
数据结构·算法
程序员清风12 小时前
算法与数据结构入门:复杂度、数组与链表
数据结构·算法·链表
Logic10116 小时前
C语言/数据结构排序题解:三个数的最大乘积——排序后比较两种候选情况
c语言·数据结构·数组·排序·时间复杂度·算法题·负数处理
殷色玫瑰17 小时前
C++ string类详解:常用接口、字符串操作与模拟实现
java·linux·c语言·开发语言·数据结构·c++
写后端的胖头鱼18 小时前
时间复杂度 & 空间复杂度
java·数据结构·算法·时间复杂度·空间复杂度
多弗朗皮卡丘18 小时前
数据结构番外:环形队列
数据结构·c
50万马克的面包19 小时前
顺序表和链表_精华知识点_CSDN博客
数据结构·链表