跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

递归算法实战:汉诺塔与合并有序链表详解

递归算法核心在于宏观视角,即相信函数的功能而非纠结细节展开。通过汉诺塔与合并两个有序链表两道经典题目,演示如何拆解问题规模及处理边界条件。汉诺塔展示了将 n 个盘子移动转化为 n-1 个子问题的策略,链表合并则利用递归简化指针操作。理解递归结束条件与函数调用逻辑,能有效消除对递归的恐惧感,提升算法解题思路。

颠三倒四发布于 2026/3/29更新于 2026/9/1161 浏览
递归算法实战:汉诺塔与合并有序链表详解

递归算法核心思维

很多人初次接触递归时,往往对代码的执行流程感到困惑甚至恐惧。其实理解递归的关键在于建立宏观视角:不要过度纠结函数调用自己的细节展开,而是相信函数的功能。

就像我们调用一个加法函数是为了利用它的计算能力一样,在递归中调用自身也是为了实现某个特定目标。以归并排序为例,mergesort 的功能是将无序数组变为有序。当我们调用 mergesort(left) 和 mergesort(right) 时,只需假设它们已经完成了各自部分的排序任务,剩下的工作就是合并这两个有序部分。这种'信任'是编写递归逻辑的基础,同时必须确保存在明确的递归结束条件,防止无限循环。

1. 汉诺塔

题目描述

有三根柱子 A、B、C,A 柱上有 n 个大小不同的圆盘,从小到大叠放。要求将 A 柱上的所有盘子移动到 C 柱,移动过程中大盘子不能压在小盘子上面,且每次只能移动一个盘子。

解法思路

这是一个经典的递归问题。我们可以从简单情况推导:

  • n=1:直接将盘子从 A 移到 C。
  • n=2:借助 B 柱,先将小盘移到 B,大盘移到 C,最后小盘移到 C。
  • n>2:策略一致。将 A 上 n-1 个盘子移到 B(借助 C),将最大的盘子移到 C,再将 B 上的 n-1 个盘子移到 C(借助 A)。

核心在于将规模为 n 的问题拆解为规模为 n-1 的子问题。当规模缩减到 1 时,直接执行移动操作。

C++ 实现

class Solution {
public:
    void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {
        dfs(A, B, C, A.size());
    }

private:
    void dfs(vector<int>& x, vector<int>& y, vector<int>& z, int n) {
        if (n == 1) {
            // 递归结束条件:x 柱中只有一个盘子,直接放到 z 柱即可
            z.push_back(x.back());
            x.pop_back();
            return;
        }
        // 先将 n-1 个盘中利用 z 柱放到 y 柱上
        dfs(x, z, y, n - 1);
        // 再将 x 柱中最底下的盘中放到 z 柱上
        z.push_back(x.back());
        x.pop_back();
        // 最后将 y 柱上 n-1 个盘子利用 x 柱放到 z 柱上
        dfs(y, x, z, n - 1);
    }
};

汉诺塔流程解析 汉诺塔流程解析 汉诺塔流程解析

2. 合并两个有序链表

题目描述

将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

解法思路

递归处理链表的核心在于定义好函数的职责:

  1. 函数含义:接收两个链表的头结点,返回合并后的头结点。
  2. 函数体:比较两个头结点的值,较小的那个作为当前合并链表的头,其 next 指针指向剩余部分的递归结果。
  3. 递归出口:当其中一个链表为空时,直接返回另一个链表。

注意:链表操作务必画图辅助,理清指针指向关系。

C++ 实现

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        // 递归的结束条件为当其中一个链表走到头,返回另一个链表当前递归位置
        if (list1 == nullptr) {
            return list2;
        }
        if (list2 == nullptr) {
            return list1;
        }
        
        if (list1->val > list2->val) {
            // list2 的头节点更小,则将 list1 和 list2->next 放入该函数中实现两个链表的合并
            // 我相信函数能帮我实现出来,这也就是宏观视角看待递归
            list2->next = mergeTwoLists(list1, list2->next);
            return list2;
        } else {
            // 同理 list1 的头节点更小也是如此
            list1->next = mergeTwoLists(list1->next, list2);
            return list1;
        }
    }
};

链表合并流程解析

掌握递归的关键在于相信函数功能的宏观视角,避免陷入递归展开的细节泥潭。通过这两道经典题目,希望能帮助大家消除对递归的恐惧,建立起清晰的解题思路。

目录

  1. 递归算法核心思维
  2. 1. 汉诺塔
  3. 题目描述
  4. 解法思路
  5. C++ 实现
  6. 2. 合并两个有序链表
  7. 题目描述
  8. 解法思路
  9. C++ 实现

更多推荐文章

查看全部
  • 浙江省人民医院基于 KingbaseES 的多院区异构多活容灾架构实践
  • CCF-CSP 第 38 次认证第二题:机器人复健指南题解
  • FastGPT 结合 MCP 协议构建工具增强型 AI Agent
  • DeepSeek-R1-Distill-Llama-8B 模型安全与对抗攻击防护
  • ALEPython 机器学习模型解释与特征分析指南
  • C++中 memcpy 和赋值拷贝的核心区别
  • VS Code 关闭 Copilot 代码自动补全设置
  • ROS 2 机器人物理属性配置与 Gazebo 仿真导入实战
  • 前端新手必备的 10 个 VS Code 插件及配置指南
  • dbswitch 异构数据库迁移与同步工具
  • Ollama 模型管理、删除及 Open WebUI 部署指南
  • 腾讯 AI 双雄对比:QClaw 与 WorkBuddy 功能解析
  • Stable Diffusion 大模型基础与选型指南
  • 基于 AI 辅助开发的在线图书借阅平台设计与实现
  • Claude Code 配置指南:通过 settings.json 优化 AI 编程体验
  • 基于 ClaudeCode 与 Figma-MCP 的 UI 设计前端还原方案
  • OpenClaw 与 Ollama 本地部署指南
  • RoboBrain2.0 具身大脑模型复现指南:统一感知推理与规划
  • MiniMax 海螺 AI 视频:图片与文本生成高质量视频
  • Spring Boot 优雅停机演进:原理与最佳实践

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online