跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++算法

C++ 递归经典案例:汉诺塔问题详解

汉诺塔是递归算法的典型应用。问题要求将 n 个盘子从 A 柱移至 C 柱,借助 B 柱,且大盘不能压小盘。解法核心在于分治:将 n-1 个盘子移至辅助柱,移动最大盘至目标柱,再将 n-1 个盘子移至目标柱。递归终止条件为 n=1。该算法时间复杂度为 O(2^n),空间复杂度取决于递归深度 O(n)。代码通过 DFS 实现状态转移,需注意栈溢出风险及参数传递效率。

NodeJser发布于 2026/3/27更新于 2026/4/283 浏览
C++ 递归经典案例:汉诺塔问题详解

C++ 递归经典案例:汉诺塔问题详解

问题描述

汉诺塔(Tower of Hanoi)是递归算法的经典入门题。规则如下:

  • 有三根柱子,分别记为 A、B、C。
  • A 柱上有 n 个大小不同的圆盘,从小到大叠放。
  • 目标是将所有盘子从 A 移动到 C。
  • 移动过程中,大盘子不能压在小盘子上面。
  • 每次只能移动一个盘子。

题目链接:面试题 08.06. 汉诺塔问题 - LeetCode

解题思路

面对这个问题,直接思考如何一次性移动 n 个盘子会非常复杂。作为工程师,我们习惯将大问题拆解为小问题。这里的核心思想是分治法配合递归。

假设我们要把 n 个盘子从 A 移到 C,借助 B:

  1. 第一步:先把 A 上面的 n-1 个盘子看作一个整体,借助 C 移动到 B 上。此时 A 只剩下最大的那个盘子,B 上有 n-1 个小盘子。
  2. 第二步:将 A 中剩下的最大盘子直接移动到 C 上。这是合法的,因为 C 是空的或者上面只有比它大的盘子(实际上此时 C 是空的)。
  3. 第三步:现在问题变成了把 B 上的 n-1 个盘子移动到 C 上,借助 A。这完全重复了第一步的逻辑,只是起始和终点变了。

当 n=1 时,不需要拆分,直接从源柱子移到目标柱子即可。这就是递归的终止条件。

关键点说明

  • 辅助柱子的角色:在递归过程中,辅助柱子(B)的角色是动态变化的。第一次调用时它是中间站,第二次调用时它变成了起点。代码中通过参数传递来体现这种变化。
  • 状态转移:dfs(A, C, B, n-1) 表示把 A 的 n-1 个移到 B(C 作辅助),dfs(B, A, C, n-1) 表示把 B 的 n-1 个移到 C(A 作辅助)。注意参数的顺序变化。

参考实现

下面是基于 C++ STL vector 的实现,模拟栈的操作。

#include <vector>
using namespace std;

class Solution {
public:
    // 深度优先搜索,负责具体的移动逻辑
    void dfs(vector<int>& A, vector<int>& B, vector<int>& C, int n) {
        // 递归终止条件:只剩一个盘子,直接移动
        if (n == 1) {
            C.push_back(A.back());
            A.();
            ;
        }
        
        
        (A, C, B, n - );
        
        
        C.(A.());
        A.();
        
        
        (B, A, C, n - );
    }

    
    {
         n = A.();
        (A, B, C, n);
    }
};
pop_back
return
// 步骤 1:将 A 上方的 n-1 个盘子移到 B(C 作为辅助)
dfs
1
// 步骤 2:将 A 中最大的盘子移到 C
push_back
back
pop_back
// 步骤 3:将 B 上的 n-1 个盘子移到 C(A 作为辅助)
dfs
1
// 主函数入口
void hanota(vector<int>& A, vector<int>& B, vector<int>& C)
int
size
dfs

工程实践笔记

在实际开发或面试中,处理这类递归问题时需要注意以下几点:

  1. 栈溢出风险:汉诺塔的递归深度与盘子数量 n 成正比。如果 n 过大(例如超过几千),可能会导致栈溢出。对于极大的 n,通常需要考虑迭代解法或数学公式优化。
  2. 参数传递:注意 vector 使用引用传递 &,避免不必要的拷贝开销,同时保证移动操作能反映到原容器上。
  3. 边界检查:虽然题目通常保证输入合法,但在生产环境中建议增加对空指针或负数的校验。
  4. 复杂度分析:
    • 时间复杂度:$O(2^n)$。每增加一个盘子,操作次数翻倍。
    • 空间复杂度:$O(n)$。取决于递归调用的栈深度。

理解汉诺塔不仅仅是为了做题,更是为了掌握'将复杂问题分解为同类子问题'的思维模式。这种思维在树形遍历、图搜索等场景中同样通用。

目录

  1. C++ 递归经典案例:汉诺塔问题详解
  2. 问题描述
  3. 解题思路
  4. 关键点说明
  5. 参考实现
  6. 工程实践笔记
  • 💰 8折买阿里云服务器限时8折了解详情
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • VSCode 配置与 Python 开发环境搭建指南
  • 首个检索增强 3D 生成模型 Phidias,统一文生图与 3D 生成任务
  • Stable Diffusion v4.10 与 ComfyUI 整合包技术指南
  • Android 一线大厂核心面试题汇总:Activity、Service 与性能优化
  • 华为 Eve 高效多模态视觉语言模型技术解析
  • 2023 电赛 H 题信号分离装置 FPGA 与 STM32 实现方案
  • MySQL 数据库基础核心概念与实战入门
  • Go 语言 Gin 框架详解与快速入门
  • LeetCode 208. 实现 Trie (前缀树) C++ 题解
  • Qwen3-VL 基于 Llama-Factory QLoRA 微调及 Ollama/LMDeploy 部署流程
  • 基于 2-RSS-1U 的双足机器人并联踝关节分析与实现
  • AngularBloc 在鸿蒙 Web 端的适配与实战指南
  • GitHub Copilot 配置性能优化与开发环境调优指南
  • 飞书 OpenClaw 接入指南:无需服务器通过长连接运行机器人
  • C++ std::string 类常用接口与模拟实现
  • 双延迟深度确定性策略梯度算法 (TD3) 详解
  • Flutter 组件 Spry 适配鸿蒙 HarmonyOS 实战:轻量级端侧 Web 服务
  • OpenClaw 对接飞书:配置多个机器人实现群聊
  • Python 图形界面与游戏开发实战:计算器、记事本及经典小游戏
  • 降低 AIGC 疑似度的实用技巧与工具指南

相关免费在线工具

  • 加密/解密文本

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