汉诺塔
1.分治法介绍
分治法:“分而治之”,就是把一个复杂的父问题分成两个或多个相同或相似的子问题,再把子问题分成更小的子问题直到最后子问题可以简单地直接求解
比如:校长想知道人数,就去问年级长,年级长想知道人数就去问班长,然后班长又去找宿舍长…
注意:对最小的子问题最后进行边界处理
2.汉诺塔问题和思路
相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如图1)。
游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。
操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
只有一个盘子要移动时:直接可以从A移动到C。步骤:A->C
有两个盘子要移动时:先把小盘子放到B,然后把大盘子放到C,最后把小盘子放到C。步骤:A->B A->C B->C
有三个盘子要移动时:步骤:A->C A->B C->B A->C B->A B->C A->C
思路:
将父问题:放n个盘子到目标位置转换为:不断求最大、次大盘子放到目标位置
n代表要移动盘子的数量
pos1代表初始位置
pos2代表中转位置
pos3代表目标位置
Hanoi的第一个参数是移动盘子的数量,第二个参数是初始位置,第三个参数是中转位置,第四个参数是目标位置。
3.代码实现汉诺塔
#include<stdio.h>
void Move(char pos1,char pos3)//初始位置移动到目标位置
{
printf("%c->%c ", pos1, pos3);
}
void Hanoi(int n, char pos1, char pos2, char pos3)
{
if(n==1)//特殊处理
{
Move(pos1, pos3);
}
else//不能不写else,因为if中的move执行结束后需要回归
{
//移动n-1个盘子到中转位置
Hanoi(n - 1, pos1, pos3, pos2);
//将最大盘子移动到目标位置
Move(pos1, pos3);
//将次大盘子作为最大盘子
Hanoi(n - 1, pos2, pos1, pos3);
}
}
int main()
{
Hanoi(1, 'A', 'B', 'C');
printf("\n");
Hanoi(2, 'A', 'B', 'C');
printf("\n");
Hanoi(3, 'A', 'B', 'C');
printf("\n");
return 0;
}