有三根圆柱,最终目的是把第一根圆柱X上的所有的圆盘按照顺序堆叠在第三根圆柱Z上,要求每一次只能移动一块圆盘,且大圆盘不能放在小圆盘的上面。
运用整体与局部的思想,这个问题可以简化为:假设有n个圆盘,我们把最上面的n-1个圆盘先移到第二根圆柱Y上①,再将第n个圆盘移动到圆柱Z上,再整体将n-1个圆盘移到圆柱Z上②。
对于① *** 作,如果我们忽略此时最下面的第n个圆盘,把X视作起始圆柱,把Y视作目标圆柱,那么就又回归到了上面的 *** 作,直到只剩下一枚圆盘在当前的起始圆柱上面,这时我们只需要进行一次移动 *** 作就可以完成问题的求解。
而对于② *** 作,我们把Y视作起始圆柱,把Z视作目标圆柱,那么剩下的X就是过渡圆柱,也划归到了之前的 *** 作里面,直到仅剩下一枚圆盘。
所以这个问题最后只剩下了两种 *** 作:整体移位和单体移位,把整体移位抽象为一个单独的函数,在函数内部递归调用自身,也就是汉诺塔问题的编程实现。
什么?你问我那个单体移位怎么搞?那个就是简单的输出语句,是结果!
代码实现 C语言代码#include#include //将n个盘子 从x 借助y 移动到z,表示一种整体的移动 //这是一种思路,而不是要具现出来的 *** 作 void move(int n,char x,char y,char z){ if (n==1) { //当这个整体的盘子数目为1的时候,也就得到了具体的实现步骤 printf("%c--->%cn",x,z); } else { //move大于1个盘子的时候实际上都是表示整体的过程 move(n-1,x,z,y); //我们要输出的是最终起到单体移位效果的那一步 //也就是把最下面的盘子移动到目标轴上 printf("%c--->%cn",x,z); move(n-1,y,x,z); } } int main() { move(3,'X','Y','Z'); return 0; }
最后的输出结果如下:
Javascript代码X—>Z
X—>Y
Z—>Y
X—>Z
Y—>X
Y—>Z
X—>Z
在Javascript实现的代码中,我定义了三个数组用于存储每个圆柱上的元素,每次单体移位的时候都使用了一次数组的栈方法模拟圆盘的移动,并将结果一并输出。
function move (n, start, transit, end, arr_x = X, arr_y = Y, arr_z = Z) { let x; if (n === 1) { x = arr_x.pop(); arr_z.push(x); console.log(start + " --" + x + "--> " + end, " X ", X, " Y ", Y, " Z ", Z); } else { move(n - 1, start, end, transit, arr_x, arr_z, arr_y); x = arr_x.pop(); arr_z.push(x); console.log(start + " --" + x + "--> " + end, " X ", X, " Y ", Y, " Z ", Z); move(n - 1, transit, start, end, arr_y, arr_x, arr_z); } } const hanoi_size = 3; const X = []; const Y = []; const Z = []; for (let i = hanoi_size; i > 0; i--) { X.push(i); } move(hanoi_size, 'X', 'Y', 'Z', X, Y, Z);
最后的输出结果如下:
X --1–> Z X [ 3, 2 ] Y [] Z [ 1 ]
X --2–> Y X [ 3 ] Y [ 2 ] Z [ 1 ]
Z --1–> Y X [ 3 ] Y [ 2, 1 ] Z []
X --3–> Z X [] Y [ 2, 1 ] Z [ 3 ]
Y --1–> X X [ 1 ] Y [ 2 ] Z [ 3 ]
Y --2–> Z X [ 1 ] Y [] Z [ 3, 2 ]
X --1–> Z X [] Y [] Z [ 3, 2, 1 ]
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)