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

递归与链表实战:汉诺塔、链表操作及快速幂详解

递归是算法基础,本文涵盖汉诺塔、链表反转合并、节点交换及快速幂四个经典案例。通过递归思想拆解规模,解决汉诺塔移动逻辑;利用指针操作实现链表的有序合并与反转;掌握两两交换节点的宏观视角;结合分治策略优化幂运算复杂度。代码采用 C++ 实现,注重边界条件处理与时间复杂度分析,适合初学者巩固递归与数据结构基础。

孤勇者发布于 2026/3/28更新于 2026/10/676 浏览
递归与链表实战:汉诺塔、链表操作及快速幂详解

在这里插入图片描述

本文设计专题一算法题链接

  • 面试题 08.06. 汉诺塔问题
  • 21. 合并两个有序链表
  • 206. 反转链表
  • 24. 两两交换链表中的节点
  • 50. Pow(x, n)

1 汉诺塔问题

题目描述

在这里插入图片描述

汉诺塔是递归思想的经典入门题。规则很简单:有三根柱子 A(起始)、B(辅助)、C(目标)。A 柱上有 n 个盘子,从小到大叠放。目标是将所有盘子从 A 移到 C,每次只能移动一个盘子,且大盘子不能放在小盘子上面。

递归思想

解决这个问题的关键在于将规模为 n 的问题分解为规模更小的子问题。

基本情况 当 n = 1 时,直接将 A 最上面的盘子移到 C 即可终止。

递归分解 若要将 A 上的 n 个盘子移到 C,可以拆解为三步:

  1. 将 A 上除了最底下的盘子(即上面 n-1 个)移到 B(借助 C 作为辅助);
  2. 将 A 最底下的最大盘子移到 C;
  3. 将 B 上的 n-1 个盘子移到 C(借助 A 作为辅助)。

这样,大问题就被拆成了两个规模为 n-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>& a, vector<int>& b, vector<int>& c, int n) {
        if (n == 1) {
            c.push_back(a.back());
            a.pop_back();
            return;
        }
        // 将 n-1 个盘子从 A 移到 B
        dfs(a, c, b, n - 1);
        // 将最大的盘子从 A 移到 C
        c.push_back(a.back());
        a.pop_back();
        // 将 n-1 个盘子从 B 移到 C
        dfs(b, a, c, n - 1);
    }
};

提示:如果是笔试中遇到这种纯逻辑题,有时可以直接赋值 c = a;,但在面试或学习中,理解递归过程才是核心。

2 合并两个有序链表

题目描述

在这里插入图片描述

给定两个升序链表,将它们合并成一个新的升序链表并返回。

解题思路

利用递归的特性,每次比较两个链表的头节点,较小的那个作为当前结果的头,然后递归处理剩余部分。

算法实现(C++)

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        // 递归出口:如果其中一个为空,直接返回另一个
        if (l1 == nullptr) return l2;
        if (l2 == nullptr) return l1;

        // 比较大小,选择较小的节点作为当前头
        if (l1->val <= l2->val) {
            l1->next = mergeTwoLists(l1->next, l2);
            return l1;
        } else {
            l2->next = mergeTwoLists(l1, l2->next);
            return l2;
        }
    }
};

3 反转链表

题目描述

在这里插入图片描述

给定单链表的头节点,反转该链表并返回新的头节点。

解题思路

递归反转的核心在于:假设 reverseList(head->next) 已经完成了后续节点的反转,此时只需要将当前节点的 next 指向它自己,并将原 next 的 next 指向当前节点即可。

算法实现(C++)

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;

        return newHead;
    }
};

4 两两交换链表中的节点

题目描述

在这里插入图片描述

给定链表,两两交换其中的节点,并返回交换后的新头节点。

解题思路

宏观角度看,先交换前两个节点,然后递归处理剩下的部分。注意边界条件:如果节点为空或只剩一个节点,则无法交换。

算法实现(C++)

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        // 出口:节点为空或者是个尾节点,就不能交换
        if (head == nullptr || head->next == nullptr) return head;

        // 递归处理后续节点
        auto tmp = swapPairs(head->next->next);
        
        // 交换当前两个节点
        auto ret = head->next;
        head->next->next = head;
        head->next = tmp;

        return ret;
    }
};

5 Pow(x, n)

题目描述

在这里插入图片描述

计算 x 的 n 次幂。

解题思路

暴力循环的时间复杂度是 O(n),对于大数会超时。这里使用快速幂算法(分治法),将时间复杂度降低到 O(log n)。核心思想是 x^n = (x^(n/2))^2,如果 n 是奇数再乘一个 x。

算法实现(C++)

class Solution {
public:
    double myPow(double x, int n) {
        // 处理负数次幂的情况
        return n < 0 ? 1.0 / Pow(x, -(long long)n) : Pow(x, n);
    }

private:
    double Pow(double x, long long n) {
        // 递归出口
        if (n == 0) return 1.0;

        // 递归计算一半
        double tmp = Pow(x, n / 2);
        
        // 根据奇偶性返回结果
        return n % 2 == 0 ? tmp * tmp : tmp * tmp * x;
    }
};

以上五个题目涵盖了递归在数学问题、数据结构操作及优化算法中的典型应用。掌握这些模式后,面对类似的递归结构题会有更清晰的思路。

目录

  1. 本文设计专题一算法题链接
  2. 1 汉诺塔问题
  3. 题目描述
  4. 递归思想
  5. 算法实现(C++)
  6. 2 合并两个有序链表
  7. 题目描述
  8. 解题思路
  9. 算法实现(C++)
  10. 3 反转链表
  11. 题目描述
  12. 解题思路
  13. 算法实现(C++)
  14. 4 两两交换链表中的节点
  15. 题目描述
  16. 解题思路
  17. 算法实现(C++)
  18. 5 Pow(x, n)
  19. 题目描述
  20. 解题思路
  21. 算法实现(C++)

更多推荐文章

查看全部
  • 基于 Claude MCP 协议的智能体落地示例
  • Python 二级考试基础操作题真题及参考代码汇总
  • Linux 网络基础:TCP/IP 协议栈与分层模型解析
  • AI 时代前端设计稿生成实战:三种高效工具流
  • AIGC 降重实用软件推荐:免费与高性价比工具汇总
  • Flutter for OpenHarmony 实战:通义万相 AIGC 联调与相册持久化
  • 四大 AI 编程工具深度对比:TRAE、Qoder、Cursor 与 Copilot 选型指南
  • 2024 中国“大模型 + 智能客服”最佳实践案例 TOP10 发布
  • C++ STL list 容器底层实现详解
  • Stable Diffusion v4.10 与 ComfyUI 整合包使用指南
  • lora-scripts 使用指南:Stable Diffusion 与 LLaMA 2 模型微调全流程
  • 网络安全入门教程:从零开始构建安全防御体系与渗透测试技能
  • AI 写代码需求不对齐?一文教你需求对齐技巧
  • OpenClaw v2026.3.7 版本功能详解:AI 代理框架更新
  • 内容创作模式解析:UGC、PGC、PUGC、OGC、MGC、BGC 与 AIGC
  • OpenClaw 接入飞书机器人与 Ollama 本地大模型实战
  • RoboChallenge 发布具身智能年度报告:4 万次真机测试显示最高成功率仅 51%
  • C++ const 关键字详解:变量、指针与函数用法
  • 2025 年 12 月 GESP C++ 四级真题解析
  • 人工智能:大模型分布式训练与高效调参技术实战

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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