汉诺塔(Hanoi)又称河内塔问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
首先以三层汉诺塔为例说明:
三根柱子分别编号为A,B,C,圆盘由小到大编号分别为1,2,3,则实现借助柱子B实现圆盘从A到C的过程如下:
圆盘个数 移动次数 圆盘编号 移动步骤
1 1 1 A->C
圆盘个数 移动次数 圆盘编号 移动步骤
2 1 1 A->B
2 2 2 A->C
2 3 1 B->C
圆盘个数 移动次数 圆盘编号 移动步骤
3 1 1 A->C
3 2 2 A->B
3 3 1 C->B 3 4 3 A->C
3 5 1 B->A
3 6 2 B->C
3 7 1 A->C2、实现2个圆盘从A->B,A->C,B->C等执行的操作均相同;
推论:当有n个圆盘时,可分解为n-1,n-2,n-3.....2个圆盘执行,形成递归,n-1个柱子每次均要先执行借助C实现A到B,再执行A到C,最后执行借助A实现B到C的过程。
当只有1个圆盘时,MATLAB代码实现如下:
function hanoi1t
global A B C m
global move_times pause_times
pause_times=1;
move_times=0;
clc;
subplot(1,3,1);
line([-1 1],[1 1],'LineWidth',30);
axis([-1.5,1.5,0,3]);
axis off;
line([0 0],[1 3],'LineWIdth',10,'color','black');
subplot(1,3,2);
line([0 0],[1 3],'LineWIdth',10,'color','black');
axis([-1.5,1.5,0,3]);
axis off;
subplot(1,3,3);
line([0 0],[1 3],'LineWIdth',10,'color','black');
axis([-1.5,1.5,0,3]);
axis off;
pause(pause_times);
clf;
move_times=move_times+1;
fprintf('moved %d times\n',move_times);
subplot(1,3,3);
line([-1 1],[1 1],'LineWidth',30);
axis([-1.5,1.5,0,3]);
axis off;
line([0 0],[1 3],'LineWIdth',10,'color','black');
subplot(1,3,2);
line([0 0],[1 3],'LineWIdth',10,'color','black');
axis([-1.5,1.5,0,3]);
axis off;
subplot(1,3,1);
line([0 0],[1 3],'LineWIdth',10,'color','black');
axis([-1.5,1.5,0,3]);
axis off;
运行结果:
当圆盘个数为n时:
function hannuota(n,ta1,ta2,ta3)
%汉诺塔
if n==1
fprintf('%c-->%c\n',ta1,ta3);
else
hannuota(n-1,ta1,ta3,ta2);
fprintf('%c-->%c\n',ta1,ta3);
hannuota(n-1,ta2,ta1,ta3);
end
end