29. 分治算法
一、什么是分治算法
分治算法(Divide and Conquer)是一种基于多级决策解决问题的重要算法范式。其基本思想是将一个难以直接解决的大问题,分割成一些规模较小的、可以独立求解的问题,以便各个击破,分而治之,最后合并各个子问题的解得到原问题的解。
分治算法通常包含三个主要步骤:
- 分解(Divide) :将原问题分解为若干个规模较小、相互独立、与原问题形式相同的子问题。这些子问题可以递归地求解。
- 解决(Conquer) :若子问题规模较小且易于解决时,则直接解决。若子问题的规模仍然较大,可以继续递归地分解,直到问题变得足够小,可以直接求解。
- 合并(Merge) :将各个子问题的解合并成原问题的解。这一步通常需要一些额外的工作,以整合子问题的结果。
分治算法的关键在于如何有效地分解问题,并且能够在合并子问题的解时保持高效。同时,分治算法也要求分解出的子问题相互独立,没有交叉影响,这样才能保证分治的正确性和效率。
二、汉诺塔问题
汉诺塔(又称河内塔)是一个源于印度古老传说的益智玩具。大梵天在创造世界的时候做了三根金刚石柱子,其中一根柱子上从下往上按照大小顺序摞着 64 片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上,并且规定在小圆盘上不能放大圆盘,三根柱子之间一次只能移动一个圆盘。这个传说后来演变成了汉诺塔游戏。
汉诺塔的解法可以简单描述为:假设有三个柱子标为 A、B、C,要由 A 搬至 C。在只有一个盘子时,直接将其搬至 C。若有 n 个盘子,则移动的次数为 。具体步骤是:先将上面的 n-1 个盘子从 A 移至 B,再将最大的盘子从 A 移至 C,最后将 n-1 个盘子从 B 移至 C。这个过程可以递归地进行,直到所有的盘子都移到 C 柱上。
#include <stdio.h>
void HanoiTower(int n, char a, char b, char c);
int main(void)
{
int n = 0;
printf("请输入盘子数:\n");
scanf("%d", &n);
HanoiTower(n, 'A', 'B', 'C');
return 0;
}
/**
* @brief 汉诺塔问题
*
* @param n 多少个盘子
* @param a 第1个柱子
* @param b 第2个柱子
* @param c 第3个柱子
*/
void HanoiTower(int n, char a, char b, char c)
{
if (n == 1) // 如果只有一个盘子,直接从 a 移动到 c
{
printf("第 1 个盘从 %c 到 %c\n", a, c);
}
else
{
HanoiTower(n - 1, a, c, b); // 最上面的n - 1个盘子从a移动到b,中间使用c
printf("第 %d 个盘从 %c 到 %c\n", n, a, c);
HanoiTower(n - 1, b, a, c); // 把b塔所有的盘子移动到c,中间使用a
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南