在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:
(1) 每次只能移动一个盘子;
(2) 盘子只能从柱子顶端滑出移到下一根柱子;
(3) 盘子只能叠在比它大的盘子上。
大致思路:
有n个盘子,从A柱到C柱
1、当n=1时,A->C
2、当n=2时,A->B A->C B->C
3、当n=3时,A->C A->B C->B A->C B->A B->C A->C
。。。。。
要将 A 柱子上最下面的盘子移到 C 柱子上,最下面的盘子也就是第 n 个盘子,那么要移动第 n 个盘子,我们要确保两个条件成立
第一个: A 柱子只剩下第 n 个盘子
第二个:C 柱子上没有盘子(或者换一种说法就是除了第 n 个盘子留在 A 柱子外,其余的 n-1 个盘子全部移到 B 柱子上)
从结果来看,n盘子必须是A->C,此时其它盘子都在B柱,下一流程就是为了把n-1盘子从B柱移动到C柱,也就是n-1盘子是B->C,这时候n-2个盘子都在A柱了,不断重复流程,直至把所有盘子都移动到C柱
//递归函数
function move($n,&$A, &$B, &$C){
if($n==1){//递归终止
array_push($C,array_pop($A));
return;
}else{//拆解子问题
$this->move($n-1,$A,$C,$B);//把A柱的n-1个盘子通过C柱全部移动到B柱,C柱留空
array_push($C,array_pop($A));//然后把A柱第n个盘子直接移动到C柱
$this->move($n-1,$B,$A,$C);//最后把B柱的n-1个盘子通过A柱全部移动到C柱
}
}