单链表反转:从基础到进阶的完整指南

作者:oioihoii日期:2025/11/6

单链表反转是数据结构与算法中的经典问题,它不仅考察对链表结构的理解,也考验编程思维和技巧。本文将带你从基础实现到高级应用,全面掌握单链表反转。

1. 理解单链表

在深入反转算法之前,我们先回顾单链表的基本结构:

1class ListNode:
2    def __init__(self, val=0, next=None):
3        self.val = val
4        self.next = next
5

单链表的特点是每个节点包含数据和指向下一个节点的指针,只能单向遍历。

2. 基础反转方法

2.1 迭代法(最常用)

核心思想:逐个改变节点指向,从前往后反转。

1def reverse_list_iterative(head):
2    prev = None
3    current = head
4    
5    while current:
6        # 保存下一个节点
7        next_temp = current.next
8        # 反转指针
9        current.next = prev
10        # 移动指针
11        prev = current
12        current = next_temp
13    
14    return prev  # 新的头节点
15

执行过程可视化

1原链表: 12345None
2
3步骤1: None1  2345None
4步骤2: None12  345None
5步骤3: None123  45None
6...
7结果: None12345
8

2.2 递归法

核心思想:通过递归到达链表末端,然后从后往前反转。

1def reverse_list_recursive(head):
2    # 递归终止条件
3    if not head or not head.next:
4        return head
5    
6    # 递归到最后一个节点
7    new_head = reverse_list_recursive(head.next)
8    
9    # 反转指针
10    head.next.next = head
11    head.next = None
12    
13    return new_head
14

递归过程分析

1reverse(1)
2  reverse(2)
3    reverse(3)
4      reverse(4)
5        reverse(5) → 返回5
6      5.next = 4, 4.next = None
7    5.next = 3, 3.next = None
8  5.next = 2, 2.next = None
95.next = 1, 1.next = None
10

3. 进阶反转技巧

3.1 反转部分链表

反转链表中从位置 m 到 n 的部分:

1def reverse_between(head, m, n):
2    if not head or m == n:
3        return head
4    
5    dummy = ListNode(0)
6    dummy.next = head
7    prev = dummy
8    
9    # 移动到第m-1个节点
10    for _ in range(m - 1):
11        prev = prev.next
12    
13    # 开始反转
14    current = prev.next
15    for _ in range(n - m):
16        temp = current.next
17        current.next = temp.next
18        temp.next = prev.next
19        prev.next = temp
20    
21    return dummy.next
22

3.2 K个一组反转链表

每 k 个节点一组进行反转,不足 k 的保持原样:

1def reverse_k_group(head, k):
2    def reverse_sublist(start, end):
3        prev, curr = None, start
4        while curr != end:
5            next_temp = curr.next
6            curr.next = prev
7            prev = curr
8            curr = next_temp
9        return prev
10    
11    # 检查是否有k个节点
12    node = head
13    for _ in range(k):
14        if not node:
15            return head
16        node = node.next
17    
18    # 反转前k个节点
19    new_head = reverse_sublist(head, node)
20    # 递归处理剩余部分
21    head.next = reverse_k_group(node, k)
22    
23    return new_head
24

3.3 交替反转

第一个k个节点反转,下一个k个节点保持,如此交替:

1def reverse_alternate_k_nodes(head, k):
2    if not head or k <= 1:
3        return head
4    
5    current = head
6    prev = None
7    reverse = True
8    
9    while current:
10        if reverse:
11            # 反转k个节点
12            section_start = current
13            section_prev = None
14            count = 0
15            
16            # 检查是否有足够的节点
17            temp = current
18            for _ in range(k):
19                if not temp:
20                    break
21                temp = temp.next
22            
23            # 反转当前段
24            while current and count < k:
25                next_temp = current.next
26                current.next = section_prev
27                section_prev = current
28                current = next_temp
29                count += 1
30            
31            # 连接已反转部分
32            if prev:
33                prev.next = section_prev
34            else:
35                head = section_prev
36            
37            section_start.next = current
38            prev = section_start
39            reverse = False
40        else:
41            # 跳过k个节点
42            count = 0
43            while current and count < k:
44                prev = current
45                current = current.next
46                count += 1
47            reverse = True
48    
49    return head
50

4. 特殊场景反转

4.1 反转链表的前N个节点

1def reverse_first_n(head, n):
2    successor = None
3    
4    def reverse_n(node, count):
5        nonlocal successor
6        if count == 1:
7            successor = node.next
8            return node
9        
10        last = reverse_n(node.next, count - 1)
11        node.next.next = node
12        node.next = successor
13        return last
14    
15    return reverse_n(head, n)
16

4.2 从末尾开始反转

1def reverse_from_end(head, k):
2    # 先找到总长度
3    length = 0
4    current = head
5    while current:
6        length += 1
7        current = current.next
8    
9    # 转换为从头开始的位置
10    m = length - k + 1
11    return reverse_between(head, m, length)
12

5. 性能分析与比较

方法时间复杂度空间复杂度适用场景
迭代法O(n)O(1)通用,最常用
递归法O(n)O(n)代码简洁,栈深度受限
部分反转O(n)O(1)局部操作
K组反转O(n)O(n/k)批量处理

6. 实战技巧与注意事项

6.1 边界情况处理

  • 空链表
  • 单节点链表
  • 反转位置超出范围
  • k值大于链表长度

6.2 调试技巧

1def print_list(head):
2    """打印链表用于调试"""
3    result = []
4    current = head
5    while current:
6        result.append(str(current.val))
7        current = current.next
8    print(" → ".join(result) + " → None")
9

6.3 常见错误

  1. 忘记处理头节点的更新
  2. 指针丢失(在改变next前未保存)
  3. 循环链表的形成
  4. 边界条件处理不完整

7. 综合练习

题目:给定链表 1→2→3→4→5→6→7,要求实现:

  1. 完全反转
  2. 反转2-5位置
  3. 每3个一组反转
  4. 交替每2个节点反转
1# 测试用例
2def create_sample_list():
3    nodes = [ListNode(i) for i in range(1, 8)]
4    for i in range(len(nodes)-1):
5        nodes[i].next = nodes[i+1]
6    return nodes[0]
7
8# 测试各种反转方法
9head = create_sample_list()
10print("原链表:")
11print_list(head)
12
13print("\n完全反转:")
14print_list(reverse_list_iterative(create_sample_list()))
15
16print("\n反转位置2-5:")
17print_list(reverse_between(create_sample_list(), 2, 5))
18
19print("\n每3个一组反转:")
20print_list(reverse_k_group(create_sample_list(), 3))
21

总结

单链表反转是算法学习中的重要里程碑。掌握从基础到进阶的各种反转技巧,不仅能够解决链表相关问题,更能培养严谨的编程思维和指针操作能力。建议通过大量练习来熟练掌握这些技巧,并理解每种方法适用的场景。

记住:多画图理解指针变化,多写代码加深印象,这是掌握链表问题的关键!


单链表反转:从基础到进阶的完整指南》 是转载文章,点击查看原文


相关推荐


前端基础:从0到1实现简单网页效果(一)
<但凡.2025/11/1

目录 1、HTML 概述 2、HTML 的基本结构 3、HTML 常用标签 文本标签 链接与图片 列表 表格 表单 HTML5 新特性 HTML 与 CSS/JavaScript 的协作 HTML 开发工具 学习资源 4、HTML 标签拓展 结构标签 文本标签 链接与媒体标签 列表标签 表格标签 表单标签 元信息标签 语义标签 5、HTML 常用全局属性 表单相关属性 链接与媒体属性 事件处理属性 其他实用属性 6、HTML闭合与非闭合标签


大模型安全:从对齐问题到对抗性攻击的深度分析
鲁大猿2025/10/30

引言 随着大语言模型(LLM)在自然语言处理任务中展现出惊人能力,其安全性问题已成为学术界和工业界关注的焦点。大模型安全不仅关乎技术可靠性,更涉及伦理道德、社会影响和实际应用风险。本文从技术角度深入分析大模型面临的安全挑战及其解决方案。 一、大模型安全的多维框架 大模型安全可划分为三个层次:基础安全、对齐安全和应用安全。基础安全关注模型训练过程的稳定性;对齐安全确保模型行为与人类价值观一致;应用安全则针对具体部署场景中的风险。 从技术视角看,大模型安全的核心问题可归纳为: 价值对齐问题:如何将


Python 的内置函数 divmod
IMPYLH2025/10/27

Python 内建函数列表 > Python 的内置函数 divmod Python 的内置函数 divmod() 是一个实用的数学运算函数,它能够同时返回两个数值相除的商和余数。这个函数接受两个非复数数字作为参数,返回一个包含两个元素的元组,第一个元素是两数相除的商,第二个元素是余数。 def divmod(x, y): ''' 返回整数除法时的商和余数 :param x: 被除数 :param y: 除数 :return: 商和余数的元组


从LIS到全院区多活:浙江省人民医院“信创样板”全景复盘
oioihoii2025/10/25

2025年10月,浙江省人民医院(下称“浙人医”)宣布:LIS(检验信息系统)在越城、朝晖、望江山、富阳四大院区完成异构多活部署,实现RPO=0、RTO≤10 min的6级容灾,业务连续性99.99%,数据调用效率提升60%。这是国内首个多院区集团化医院在核心系统上线国产数据库并跑通异地多活的公开案例。 一、为什么先动LIS 业务高敏感:日均2.3万管标本,报告延迟直接影响门诊流速与住院手术排程。 体量可控:4TB数据、420个接口,既覆盖检验仪器、HIS、PACS,又不会出现一次性切换风险


Spring AI Alibaba Admin 开源!以数据为中心的 Agent 开发平台
阿里云云原生2025/10/22

作者:孔可青 背景与挑战 1.1 行业背景:AI Agent 迈入规模化落地新阶段 随着生成式 AI 技术逐步成熟,AI Agent 已经越过技术炒作周期的峰值,进入大规模探索与产业落地的关键阶段。越来越多的企业开始将 AI Agent 应用于智能客服、自动化运营、辅助决策等核心业务场景,推动智能化升级。 在此背景下,Spring AI Alibaba 作为开源的 AI Agent 开发框架,致力于为 Java 生态开发者提供一套标准化、可扩展、生产就绪的开发体系。框架支持从基础 Agent 构


猿辅导Java面试真实经历与深度总结(一)
360_go_php2025/10/22

​  猿辅导Java面试 的文章,结构清晰、列出的几个核心问题,并附详细答案。文章既适合复习,也适合面试现场讲解。  ​编辑 猿辅导Java面试核心知识点解析 Java面试中,垃圾回收、锁机制以及高并发集合类是常考知识点。本文将结合实际面试题,系统讲解这些内容。 ---​编辑 一、垃圾收集器(Garbage Collector, GC) 概念:   垃圾收集器负责自动管理内存,回收无用对象,避免内存泄漏和程序崩溃。Java虚拟机中,垃圾收集器主要作用于堆内存。​编辑 常见垃圾收集器: Ser


Python编程实战 · 基础入门篇 | Python的缩进与代码块
程序员爱钓鱼2025/10/20

在学习任何编程语言时,我们都会遇到一个问题:代码的层次结构该怎么表示? 在 C、Java 等语言中,开发者通常用大括号 {} 来表示代码块。 但在 Python 中,一切都不同。 Python 没有大括号、没有 begin 和 end,它用一种更自然的方式——缩进,来体现代码逻辑。 这不仅是 Python 的语法规则,更是它优雅、简洁风格的核心体现。 一 为什么 Python 要用缩进 Python 的设计哲学之一是 “代码的可读性至上”。 缩进是一种强制性的格式要求,让程序结构一目了然,不


gRPC Python 详细入门教程(一)
kuan_li_lyg2025/10/19

系列文章目录 目录 系列文章目录 前言 0.1 主要应用场景 0.2 核心优势特性 一、快速入门 1.1 先决条件 1.1.1 gRPC 1.1.2 gRPC 工具 1.2 下载示例代码 1.3 运行一个 gRPC 应用程序 1.4 更新gRPC服务 1.5 生成 gRPC 代码 1.6 更新并运行应用程序 1.6.1 更新服务器 1.6.2 更新客户端 1.6.3 运行! 二、基础教程 2.1 为何选择gRPC? 2.2 示例代码与环境配置 2.3 定


AI无人机助力生态智慧农田倒伏检测与防控,基于最新以注意力为核心的YOLOv12全系列【n/s/m/l/x】参数模型开发构建无人机航拍智慧生态农田场景下稻田作物倒伏智能化检测预警系统
Together_CZ2025/10/17

在广袤的稻田中,农作物的生长状态直接关系到粮食的产量和质量。然而,自然环境的不确定性,如大风等恶劣天气,常常给农作物带来倒伏的风险。倒伏不仅会导致产量下降,还会给后续的机械化收割带来极大的困难,甚至造成严重的浪费。传统的农田作业模式在面对这些问题时显得力不从心,而随着 AI 智能化技术的快速发展,传统农业正迎来一场深刻的变革。 一、传统农田作业的困境 在传统的稻田种植中,农民们依靠丰富的经验和敏锐的观察力来管理农田。然而,面对大面积的农田,人工巡查的方式效率低下,且难以及时发现所有倒伏区域。


【Java Xml】Apache Commons Digester3解析
Lucky_Turtle2025/10/16

文章目录 概述前期准备使用1、简单读取示例2、多个标签读取示例 细节问题addSetNext顺序 参考 概述 官网 写入查看另一篇:https://blog.csdn.net/qq_45742250/article/details/153191615 前期准备 maven <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-digester3 --> <dependency> <gr

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0